Control flow typing for variables with null or undefined initializer

This commit is contained in:
Anders Hejlsberg 2016-09-29 13:04:51 -07:00
parent bd19f1db09
commit 0621f7e9a1
2 changed files with 10 additions and 4 deletions

View File

@ -3051,6 +3051,11 @@ namespace ts {
return undefined;
}
function isAutoVariableInitializer(initializer: Expression) {
let expr = initializer && skipParentheses(initializer);
return !expr || expr.kind === SyntaxKind.NullKeyword || expr.kind === SyntaxKind.Identifier && getResolvedSymbol(<Identifier>expr) === undefinedSymbol;
}
function addOptionality(type: Type, optional: boolean): Type {
return strictNullChecks && optional ? includeFalsyTypes(type, TypeFlags.Undefined) : type;
}
@ -3090,9 +3095,10 @@ namespace ts {
}
// Use control flow type inference for non-ambient, non-exported var or let variables with no initializer
// or a 'null' or 'undefined' initializer.
if (declaration.kind === SyntaxKind.VariableDeclaration && !isBindingPattern(declaration.name) &&
!(getCombinedNodeFlags(declaration) & NodeFlags.Const) && !(getCombinedModifierFlags(declaration) & ModifierFlags.Export) &&
!declaration.initializer && !isInAmbientContext(declaration)) {
!isInAmbientContext(declaration) && isAutoVariableInitializer(declaration.initializer)) {
return autoType;
}
@ -8965,7 +8971,7 @@ namespace ts {
if (isRightSideOfQualifiedNameOrPropertyAccess(location)) {
location = location.parent;
}
if (isExpression(location) && !isAssignmentTarget(location)) {
if (isPartOfExpression(location) && !isAssignmentTarget(location)) {
const type = checkExpression(<Expression>location);
if (getExportSymbolOfValueSymbolIfExported(getNodeLinks(location).resolvedSymbol) === symbol) {
return type;
@ -9146,7 +9152,7 @@ namespace ts {
if (type === autoType) {
if (flowType === autoType) {
if (compilerOptions.noImplicitAny) {
error(declaration.name, Diagnostics.Variable_0_implicitly_has_type_any_and_is_referenced_in_a_nested_function, symbolToString(symbol));
error(declaration.name, Diagnostics.Variable_0_implicitly_has_type_any_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol));
}
return anyType;
}

View File

@ -2953,7 +2953,7 @@
"category": "Error",
"code": 7033
},
"Variable '{0}' implicitly has type 'any' and is referenced in a nested function.": {
"Variable '{0}' implicitly has type 'any' in some locations where its type cannot be determined.": {
"category": "Error",
"code": 7034
},