feat(36048): handle uncalled function checks in ternaries (#36402)

This commit is contained in:
Alexander T
2020-02-20 19:29:41 +02:00
committed by GitHub
parent c8147cb601
commit bf6be75131
6 changed files with 688 additions and 10 deletions

View File

@@ -27929,7 +27929,8 @@ namespace ts {
}
function checkConditionalExpression(node: ConditionalExpression, checkMode?: CheckMode): Type {
checkTruthinessExpression(node.condition);
const type = checkTruthinessExpression(node.condition);
checkTestingKnownTruthyCallableType(node.condition, node.whenTrue, type);
const type1 = checkExpression(node.whenTrue, checkMode);
const type2 = checkExpression(node.whenFalse, checkMode);
return getUnionType([type1, type2], UnionReduction.Subtype);
@@ -31051,9 +31052,8 @@ namespace ts {
function checkIfStatement(node: IfStatement) {
// Grammar checking
checkGrammarStatementInAmbientContext(node);
const type = checkTruthinessExpression(node.expression);
checkTestingKnownTruthyCallableType(node, type);
checkTestingKnownTruthyCallableType(node.expression, node.thenStatement, type);
checkSourceElement(node.thenStatement);
if (node.thenStatement.kind === SyntaxKind.EmptyStatement) {
@@ -31063,15 +31063,15 @@ namespace ts {
checkSourceElement(node.elseStatement);
}
function checkTestingKnownTruthyCallableType(ifStatement: IfStatement, type: Type) {
function checkTestingKnownTruthyCallableType(condExpr: Expression, body: Statement | Expression, type: Type) {
if (!strictNullChecks) {
return;
}
const testedNode = isIdentifier(ifStatement.expression)
? ifStatement.expression
: isPropertyAccessExpression(ifStatement.expression)
? ifStatement.expression.name
const testedNode = isIdentifier(condExpr)
? condExpr
: isPropertyAccessExpression(condExpr)
? condExpr.name
: undefined;
if (!testedNode) {
@@ -31098,7 +31098,7 @@ namespace ts {
return;
}
const functionIsUsedInBody = forEachChild(ifStatement.thenStatement, function check(childNode): boolean | undefined {
const functionIsUsedInBody = forEachChild(body, function check(childNode): boolean | undefined {
if (isIdentifier(childNode)) {
const childSymbol = getSymbolAtLocation(childNode);
if (childSymbol && childSymbol.id === testedFunctionSymbol.id) {
@@ -31110,7 +31110,7 @@ namespace ts {
});
if (!functionIsUsedInBody) {
error(ifStatement.expression, Diagnostics.This_condition_will_always_return_true_since_the_function_is_always_defined_Did_you_mean_to_call_it_instead);
error(condExpr, Diagnostics.This_condition_will_always_return_true_since_the_function_is_always_defined_Did_you_mean_to_call_it_instead);
}
}