From 5de3ee8ebc396e256a32dbcfc9c7afac8af586cc Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 30 Mar 2019 10:13:13 -0700 Subject: [PATCH] getIndexedAccessType for assignment target uses intersections --- src/compiler/checker.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d96eb6a6c4d..cc2dec0a705 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9875,7 +9875,7 @@ namespace ts { return false; } - function getPropertyTypeForIndexType(objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, cacheSymbol: boolean, missingType: Type) { + function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, cacheSymbol: boolean, missingType: Type) { const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined; const propName = isTypeUsableAsPropertyName(indexType) ? getPropertyNameFromType(indexType) : @@ -9898,7 +9898,6 @@ namespace ts { getNodeLinks(accessNode!).resolvedSymbol = prop; } } - const propType = getTypeOfSymbol(prop); return accessExpression && getAssignmentTargetKind(accessExpression) !== AssignmentKind.Definite ? getFlowTypeOfReference(accessExpression, propType) : @@ -9922,7 +9921,8 @@ namespace ts { if (objectType.flags & (TypeFlags.Any | TypeFlags.Never)) { return objectType; } - const indexInfo = isTypeAssignableToKind(indexType, TypeFlags.NumberLike) && getIndexInfoOfType(objectType, IndexKind.Number) || + const indexInfo = accessExpression && isAssignmentTarget(accessExpression) && isGenericObjectType(originalObjectType) ? undefined : + isTypeAssignableToKind(indexType, TypeFlags.NumberLike) && getIndexInfoOfType(objectType, IndexKind.Number) || getIndexInfoOfType(objectType, IndexKind.String) || undefined; if (indexInfo) { @@ -10105,7 +10105,7 @@ namespace ts { const propTypes: Type[] = []; let wasMissingProp = false; for (const t of (indexType).types) { - const propType = getPropertyTypeForIndexType(apparentObjectType, t, accessNode, /*cacheSymbol*/ false, missingType); + const propType = getPropertyTypeForIndexType(objectType, apparentObjectType, t, accessNode, /*cacheSymbol*/ false, missingType); if (propType === missingType) { if (!accessNode) { // If there's no error node, we can immeditely stop, since error reporting is off @@ -10121,9 +10121,9 @@ namespace ts { if (wasMissingProp) { return missingType; } - return getUnionType(propTypes); + return !accessNode || getAssignmentTargetKind(accessNode) === AssignmentKind.None ? getUnionType(propTypes) : getIntersectionType(propTypes); } - return getPropertyTypeForIndexType(apparentObjectType, indexType, accessNode, /*cacheSymbol*/ true, missingType); + return getPropertyTypeForIndexType(objectType, apparentObjectType, indexType, accessNode, /*cacheSymbol*/ true, missingType); } function getTypeFromIndexedAccessTypeNode(node: IndexedAccessTypeNode) { @@ -19570,7 +19570,7 @@ namespace ts { markAliasReferenced(parentSymbol, node); } if (!prop) { - const indexInfo = getIndexInfoOfType(apparentType, IndexKind.String); + const indexInfo = assignmentKind === AssignmentKind.None || !isGenericObjectType(leftType) ? getIndexInfoOfType(apparentType, IndexKind.String) : undefined; if (!(indexInfo && indexInfo.type)) { if (isJSLiteralType(leftType)) { return anyType;