Reuse computed type of condition expressions (#49881)

This commit is contained in:
Joost Koehoorn
2022-08-27 10:40:13 +02:00
committed by GitHub
parent 8778c1ded3
commit 71b2ba6111
5 changed files with 135 additions and 7 deletions

View File

@@ -34108,7 +34108,7 @@ namespace ts {
|| isBinaryExpression(parent) && (parent.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken || parent.operatorToken.kind === SyntaxKind.BarBarToken)) {
parent = parent.parent;
}
checkTestingKnownTruthyCallableOrAwaitableType(node.left, isIfStatement(parent) ? parent.thenStatement : undefined);
checkTestingKnownTruthyCallableOrAwaitableType(node.left, leftType, isIfStatement(parent) ? parent.thenStatement : undefined);
}
checkTruthinessOfType(leftType, node.left);
}
@@ -34685,8 +34685,8 @@ namespace ts {
}
function checkConditionalExpression(node: ConditionalExpression, checkMode?: CheckMode): Type {
checkTruthinessExpression(node.condition);
checkTestingKnownTruthyCallableOrAwaitableType(node.condition, node.whenTrue);
const type = checkTruthinessExpression(node.condition);
checkTestingKnownTruthyCallableOrAwaitableType(node.condition, type, node.whenTrue);
const type1 = checkExpression(node.whenTrue, checkMode);
const type2 = checkExpression(node.whenFalse, checkMode);
return getUnionType([type1, type2], UnionReduction.Subtype);
@@ -38391,8 +38391,8 @@ namespace ts {
function checkIfStatement(node: IfStatement) {
// Grammar checking
checkGrammarStatementInAmbientContext(node);
checkTruthinessExpression(node.expression);
checkTestingKnownTruthyCallableOrAwaitableType(node.expression, node.thenStatement);
const type = checkTruthinessExpression(node.expression);
checkTestingKnownTruthyCallableOrAwaitableType(node.expression, type, node.thenStatement);
checkSourceElement(node.thenStatement);
if (node.thenStatement.kind === SyntaxKind.EmptyStatement) {
@@ -38402,7 +38402,7 @@ namespace ts {
checkSourceElement(node.elseStatement);
}
function checkTestingKnownTruthyCallableOrAwaitableType(condExpr: Expression, body?: Statement | Expression) {
function checkTestingKnownTruthyCallableOrAwaitableType(condExpr: Expression, condType: Type, body?: Statement | Expression) {
if (!strictNullChecks) return;
helper(condExpr, body);
@@ -38417,7 +38417,7 @@ namespace ts {
? condExpr.right
: condExpr;
if (isModuleExportsAccessExpression(location)) return;
const type = checkTruthinessExpression(location);
const type = location === condExpr ? condType : checkTruthinessExpression(location);
const isPropertyExpressionCast = isPropertyAccessExpression(location) && isTypeAssertion(location.expression);
if (!(getTypeFacts(type) & TypeFacts.Truthy) || isPropertyExpressionCast) return;