@@ -4308,7 +4308,8 @@ namespace ts {
4308
4308
if (strictNullChecks && declaration.flags & NodeFlags.Ambient && isParameterDeclaration(declaration)) {
4309
4309
parentType = getNonNullableType(parentType);
4310
4310
}
4311
- const declaredType = getTypeOfPropertyOfType(parentType, text);
4311
+ const propType = getTypeOfPropertyOfType(parentType, text);
4312
+ const declaredType = propType && getDeclaredOrApparentType(propType, declaration.name);
4312
4313
type = declaredType && getFlowTypeOfReference(declaration, declaredType) ||
4313
4314
isNumericLiteralName(text) && getIndexTypeOfType(parentType, IndexKind.Number) ||
4314
4315
getIndexTypeOfType(parentType, IndexKind.String);
@@ -12039,16 +12040,6 @@ namespace ts {
12039
12040
}
12040
12041
12041
12042
function getTypeWithFacts(type: Type, include: TypeFacts) {
12042
- if (type.flags & TypeFlags.IndexedAccess) {
12043
- // TODO (weswig): This is a substitute for a lazy negated type to remove the types indicated by the TypeFacts from the (potential) union the IndexedAccess refers to
12044
- // - See discussion in https://github.com/Microsoft/TypeScript/pull/19275 for details, and test `strictNullNotNullIndexTypeShouldWork` for current behavior
12045
- const baseConstraint = getBaseConstraintOfType(type) || emptyObjectType;
12046
- const result = filterType(baseConstraint, t => (getTypeFacts(t) & include) !== 0);
12047
- if (result !== baseConstraint) {
12048
- return result;
12049
- }
12050
- return type;
12051
- }
12052
12043
return filterType(type, t => (getTypeFacts(t) & include) !== 0);
12053
12044
}
12054
12045
@@ -13162,19 +13153,20 @@ namespace ts {
13162
13153
const parent = node.parent;
13163
13154
return parent.kind === SyntaxKind.PropertyAccessExpression ||
13164
13155
parent.kind === SyntaxKind.CallExpression && (<CallExpression>parent).expression === node ||
13165
- parent.kind === SyntaxKind.ElementAccessExpression && (<ElementAccessExpression>parent).expression === node;
13156
+ parent.kind === SyntaxKind.ElementAccessExpression && (<ElementAccessExpression>parent).expression === node ||
13157
+ parent.kind === SyntaxKind.NonNullExpression ||
13158
+ parent.kind === SyntaxKind.BindingElement && (<BindingElement>parent).name === node && !!(<BindingElement>parent).initializer;
13166
13159
}
13167
13160
13168
13161
function typeHasNullableConstraint(type: Type) {
13169
13162
return type.flags & TypeFlags.TypeVariable && maybeTypeOfKind(getBaseConstraintOfType(type) || emptyObjectType, TypeFlags.Nullable);
13170
13163
}
13171
13164
13172
- function getDeclaredOrApparentType(symbol: Symbol , node: Node) {
13165
+ function getDeclaredOrApparentType(type: Type , node: Node) {
13173
13166
// When a node is the left hand expression of a property access, element access, or call expression,
13174
13167
// and the type of the node includes type variables with constraints that are nullable, we fetch the
13175
13168
// apparent type of the node *before* performing control flow analysis such that narrowings apply to
13176
13169
// the constraint type.
13177
- const type = getTypeOfSymbol(symbol);
13178
13170
if (isApparentTypePosition(node) && forEachType(type, typeHasNullableConstraint)) {
13179
13171
return mapType(getWidenedType(type), getApparentType);
13180
13172
}
@@ -13264,7 +13256,7 @@ namespace ts {
13264
13256
checkCollisionWithCapturedNewTargetVariable(node, node);
13265
13257
checkNestedBlockScopedBinding(node, symbol);
13266
13258
13267
- const type = getDeclaredOrApparentType(localOrExportSymbol, node);
13259
+ const type = getDeclaredOrApparentType(getTypeOfSymbol( localOrExportSymbol) , node);
13268
13260
const assignmentKind = getAssignmentTargetKind(node);
13269
13261
13270
13262
if (assignmentKind) {
@@ -13338,7 +13330,7 @@ namespace ts {
13338
13330
return convertAutoToAny(flowType);
13339
13331
}
13340
13332
}
13341
- else if (!assumeInitialized && !(getFalsyFlags(getApparentType( type) ) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) {
13333
+ else if (!assumeInitialized && !(getFalsyFlags(type) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) {
13342
13334
error(node, Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol));
13343
13335
// Return the declared type to reduce follow-on errors
13344
13336
return type;
@@ -15816,7 +15808,7 @@ namespace ts {
15816
15808
return unknownType;
15817
15809
}
15818
15810
}
15819
- propType = getDeclaredOrApparentType(prop, node);
15811
+ propType = getDeclaredOrApparentType(getTypeOfSymbol( prop) , node);
15820
15812
}
15821
15813
// Only compute control flow type if this is a property access expression that isn't an
15822
15814
// assignment target, and the referenced property was declared as a variable, property,
0 commit comments