(type, expr, assumeTrue)
| 71343 | // Narrow the given type based on the given expression having the assumed boolean value. The returned type |
| 71344 | // will be a subtype or the same type as the argument. |
| 71345 | function narrowType(type, expr, assumeTrue) { |
| 71346 | // for `a?.b`, we emulate a synthetic `a !== null && a !== undefined` condition for `a` |
| 71347 | if (ts.isExpressionOfOptionalChainRoot(expr) || |
| 71348 | ts.isBinaryExpression(expr.parent) && expr.parent.operatorToken.kind === 60 /* SyntaxKind.QuestionQuestionToken */ && expr.parent.left === expr) { |
| 71349 | return narrowTypeByOptionality(type, expr, assumeTrue); |
| 71350 | } |
| 71351 | switch (expr.kind) { |
| 71352 | case 79 /* SyntaxKind.Identifier */: |
| 71353 | // When narrowing a reference to a const variable, non-assigned parameter, or readonly property, we inline |
| 71354 | // up to five levels of aliased conditional expressions that are themselves declared as const variables. |
| 71355 | if (!isMatchingReference(reference, expr) && inlineLevel < 5) { |
| 71356 | var symbol = getResolvedSymbol(expr); |
| 71357 | if (isConstVariable(symbol)) { |
| 71358 | var declaration = symbol.valueDeclaration; |
| 71359 | if (declaration && ts.isVariableDeclaration(declaration) && !declaration.type && declaration.initializer && isConstantReference(reference)) { |
| 71360 | inlineLevel++; |
| 71361 | var result = narrowType(type, declaration.initializer, assumeTrue); |
| 71362 | inlineLevel--; |
| 71363 | return result; |
| 71364 | } |
| 71365 | } |
| 71366 | } |
| 71367 | // falls through |
| 71368 | case 108 /* SyntaxKind.ThisKeyword */: |
| 71369 | case 106 /* SyntaxKind.SuperKeyword */: |
| 71370 | case 206 /* SyntaxKind.PropertyAccessExpression */: |
| 71371 | case 207 /* SyntaxKind.ElementAccessExpression */: |
| 71372 | return narrowTypeByTruthiness(type, expr, assumeTrue); |
| 71373 | case 208 /* SyntaxKind.CallExpression */: |
| 71374 | return narrowTypeByCallExpression(type, expr, assumeTrue); |
| 71375 | case 212 /* SyntaxKind.ParenthesizedExpression */: |
| 71376 | case 230 /* SyntaxKind.NonNullExpression */: |
| 71377 | return narrowType(type, expr.expression, assumeTrue); |
| 71378 | case 221 /* SyntaxKind.BinaryExpression */: |
| 71379 | return narrowTypeByBinaryExpression(type, expr, assumeTrue); |
| 71380 | case 219 /* SyntaxKind.PrefixUnaryExpression */: |
| 71381 | if (expr.operator === 53 /* SyntaxKind.ExclamationToken */) { |
| 71382 | return narrowType(type, expr.operand, !assumeTrue); |
| 71383 | } |
| 71384 | break; |
| 71385 | } |
| 71386 | return type; |
| 71387 | } |
| 71388 | function narrowTypeByOptionality(type, expr, assumePresent) { |
| 71389 | if (isMatchingReference(reference, expr)) { |
| 71390 | return getTypeWithFacts(type, assumePresent ? 2097152 /* TypeFacts.NEUndefinedOrNull */ : 262144 /* TypeFacts.EQUndefinedOrNull */); |
no test coverage detected
searching dependent graphs…