Add error for missing await in conditionals

This commit is contained in:
Jack Works
2020-06-20 15:58:25 +08:00
committed by Eli Barzilay
parent ba994f1381
commit bb8b9db9f7
8 changed files with 211 additions and 10 deletions

View File

@@ -30731,7 +30731,7 @@ namespace ts {
if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken || operator === SyntaxKind.QuestionQuestionToken) {
if (operator === SyntaxKind.AmpersandAmpersandToken) {
const parent = walkUpParenthesizedExpressions(node.parent);
checkTestingKnownTruthyCallableType(node.left, leftType, isIfStatement(parent) ? parent.thenStatement : undefined);
checkTestingKnownTruthyCallableOrAwaitableType(node.left, leftType, isIfStatement(parent) ? parent.thenStatement : undefined);
}
checkTruthinessOfType(leftType, node.left);
}
@@ -31275,7 +31275,7 @@ namespace ts {
function checkConditionalExpression(node: ConditionalExpression, checkMode?: CheckMode): Type {
const type = checkTruthinessExpression(node.condition);
checkTestingKnownTruthyCallableType(node.condition, type, node.whenTrue);
checkTestingKnownTruthyCallableOrAwaitableType(node.condition, type, node.whenTrue);
const type1 = checkExpression(node.whenTrue, checkMode);
const type2 = checkExpression(node.whenFalse, checkMode);
return getUnionType([type1, type2], UnionReduction.Subtype);
@@ -34526,7 +34526,7 @@ namespace ts {
// Grammar checking
checkGrammarStatementInAmbientContext(node);
const type = checkTruthinessExpression(node.expression);
checkTestingKnownTruthyCallableType(node.expression, type, node.thenStatement);
checkTestingKnownTruthyCallableOrAwaitableType(node.expression, type, node.thenStatement);
checkSourceElement(node.thenStatement);
if (node.thenStatement.kind === SyntaxKind.EmptyStatement) {
@@ -34536,8 +34536,16 @@ namespace ts {
checkSourceElement(node.elseStatement);
}
function checkTestingKnownTruthyCallableType(condExpr: Expression, type: Type, body: Statement | Expression | undefined) {
if (!strictNullChecks) {
function checkTestingKnownTruthyCallableOrAwaitableType(condExpr: Expression, type: Type, body?: Statement | Expression) {
if (!strictNullChecks) return;
if (getFalsyFlags(type)) return;
if (getAwaitedTypeOfPromise(type)) {
errorAndMaybeSuggestAwait(
condExpr,
/*maybeMissingAwait*/ true,
Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap,
"true", getTypeNameForErrorDisplay(type), "false");
return;
}
@@ -34552,11 +34560,6 @@ namespace ts {
return;
}
const possiblyFalsy = getFalsyFlags(type);
if (possiblyFalsy) {
return;
}
// While it technically should be invalid for any known-truthy value
// to be tested, we de-scope to functions unrefenced in the block as a
// heuristic to identify the most common bugs. There are too many

View File

@@ -3256,6 +3256,10 @@
"category": "Error",
"code": 2800
},
"This condition will always return true since the Promise is always truthy.": {
"category": "Error",
"code": 2801
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",