Make for..in expressions allowed to be null/undefined (#28348)

This commit is contained in:
Wesley Wigham
2018-11-05 17:23:19 -08:00
committed by GitHub
parent 85dbc0438f
commit 929791868f
8 changed files with 95 additions and 10 deletions

View File

@@ -4766,7 +4766,7 @@ namespace ts {
// A variable declared in a for..in statement is of type string, or of type keyof T when the
// right hand expression is of a type parameter type.
if (isVariableDeclaration(declaration) && declaration.parent.parent.kind === SyntaxKind.ForInStatement) {
const indexType = getIndexType(checkNonNullExpression(declaration.parent.parent.expression));
const indexType = getIndexType(getNonNullableTypeIfNeeded(checkExpression(declaration.parent.parent.expression)));
return indexType.flags & (TypeFlags.TypeParameter | TypeFlags.Index) ? getExtractStringType(indexType) : stringType;
}
@@ -15175,6 +15175,10 @@ namespace ts {
}
return declaredType;
}
// for (const _ in ref) acts as a nonnull on ref
if (isVariableDeclaration(node) && node.parent.parent.kind === SyntaxKind.ForInStatement && isMatchingReference(reference, node.parent.parent.expression)) {
return getNonNullableTypeIfNeeded(getTypeFromFlowType(getTypeAtFlowNode(flow.antecedent)));
}
// Assignment doesn't affect reference
return undefined;
}
@@ -18489,6 +18493,14 @@ namespace ts {
);
}
function getNonNullableTypeIfNeeded(type: Type) {
const kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & TypeFlags.Nullable;
if (kind) {
return getNonNullableType(type);
}
return type;
}
function checkNonNullType(
type: Type,
node: Node,
@@ -25286,7 +25298,7 @@ namespace ts {
// Grammar checking
checkGrammarForInOrForOfStatement(node);
const rightType = checkNonNullExpression(node.expression);
const rightType = getNonNullableTypeIfNeeded(checkExpression(node.expression));
// TypeScript 1.0 spec (April 2014): 5.4
// In a 'for-in' statement of the form
// for (let VarDecl in Expr) Statement