@@ -5738,14 +5738,24 @@ namespace ts {
5738
5738
return indexedAccessTypes[objectType.id] || (indexedAccessTypes[objectType.id] = createIndexedAccessType(objectType, indexType));
5739
5739
}
5740
5740
5741
- function getPropertyTypeForIndexType(objectType: Type, indexType: Type, accessNode? : ElementAccessExpression | IndexedAccessTypeNode) {
5741
+ function getPropertyTypeForIndexType(objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode, cacheSymbol: boolean ) {
5742
5742
const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? <ElementAccessExpression>accessNode : undefined;
5743
- if (indexType.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral | TypeFlags.EnumLiteral)) {
5744
- const prop = getPropertyOfType(objectType, escapeIdentifier((<LiteralType>indexType).text));
5743
+ const propName = indexType.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral | TypeFlags.EnumLiteral) ?
5744
+ (<LiteralType>indexType).text :
5745
+ accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ?
5746
+ getPropertyNameForKnownSymbolName((<Identifier>(<PropertyAccessExpression>accessExpression.argumentExpression).name).text) :
5747
+ undefined;
5748
+ if (propName) {
5749
+ const prop = getPropertyOfType(objectType, propName);
5745
5750
if (prop) {
5746
- if (accessExpression && isAssignmentTarget(accessExpression) && isReadonlySymbol(prop)) {
5747
- error(accessExpression.argumentExpression, Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, symbolToString(prop));
5748
- return unknownType;
5751
+ if (accessExpression) {
5752
+ if (isAssignmentTarget(accessExpression) && (isReferenceToReadonlyEntity(accessExpression, prop) || isReferenceThroughNamespaceImport(accessExpression))) {
5753
+ error(accessExpression.argumentExpression, Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, symbolToString(prop));
5754
+ return unknownType;
5755
+ }
5756
+ if (cacheSymbol) {
5757
+ getNodeLinks(accessNode).resolvedSymbol = prop;
5758
+ }
5749
5759
}
5750
5760
return getTypeOfSymbol(prop);
5751
5761
}
@@ -5798,18 +5808,19 @@ namespace ts {
5798
5808
}
5799
5809
return getIndexedAccessTypeForTypeParameter(objectType, <TypeParameter>indexType);
5800
5810
}
5811
+ const apparentType = getApparentType(objectType);
5801
5812
if (indexType.flags & TypeFlags.Union && !(indexType.flags & TypeFlags.Primitive)) {
5802
5813
const propTypes: Type[] = [];
5803
5814
for (const t of (<UnionType>indexType).types) {
5804
- const propType = getPropertyTypeForIndexType(objectType , t, accessNode);
5815
+ const propType = getPropertyTypeForIndexType(apparentType , t, accessNode, /*cacheSymbol*/ false );
5805
5816
if (propType === unknownType) {
5806
5817
return unknownType;
5807
5818
}
5808
5819
propTypes.push(propType);
5809
5820
}
5810
5821
return getUnionType(propTypes);
5811
5822
}
5812
- return getPropertyTypeForIndexType(objectType , indexType, accessNode);
5823
+ return getPropertyTypeForIndexType(apparentType , indexType, accessNode, /*cacheSymbol*/ true );
5813
5824
}
5814
5825
5815
5826
function getTypeFromIndexedAccessTypeNode(node: IndexedAccessTypeNode) {
@@ -11644,55 +11655,9 @@ namespace ts {
11644
11655
return unknownType;
11645
11656
}
11646
11657
11647
- const propName = getPropertyNameForIndexedAccess(indexExpression, indexType);
11648
- if (propName !== undefined) {
11649
- const prop = getPropertyOfType(getApparentType(objectType), propName);
11650
- if (prop) {
11651
- getNodeLinks(node).resolvedSymbol = prop;
11652
- if (isAssignmentTarget(node)) {
11653
- if (isReferenceToReadonlyEntity(<Expression>node, prop) || isReferenceThroughNamespaceImport(<Expression>node)) {
11654
- error(indexExpression, Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, propName);
11655
- return unknownType;
11656
- }
11657
- }
11658
- return getTypeOfSymbol(prop);
11659
- }
11660
- }
11661
-
11662
11658
return getIndexedAccessType(objectType, indexType, node);
11663
11659
}
11664
11660
11665
- /**
11666
- * If indexArgumentExpression is a string literal or number literal, returns its text.
11667
- * If indexArgumentExpression is a constant value, returns its string value.
11668
- * If indexArgumentExpression is a well known symbol, returns the property name corresponding
11669
- * to this symbol, as long as it is a proper symbol reference.
11670
- * Otherwise, returns undefined.
11671
- */
11672
- function getPropertyNameForIndexedAccess(indexExpression: Expression, indexType: Type): string {
11673
- if (indexExpression.kind === SyntaxKind.StringLiteral || indexExpression.kind === SyntaxKind.NumericLiteral) {
11674
- return (<LiteralExpression>indexExpression).text;
11675
- }
11676
- if (indexExpression.kind === SyntaxKind.ElementAccessExpression || indexExpression.kind === SyntaxKind.PropertyAccessExpression) {
11677
- const value = getConstantValue(<ElementAccessExpression | PropertyAccessExpression>indexExpression);
11678
- if (value !== undefined) {
11679
- return value.toString();
11680
- }
11681
- }
11682
- if (checkThatExpressionIsProperSymbolReference(indexExpression, indexType, /*reportError*/ false)) {
11683
- const rightHandSideName = (<Identifier>(<PropertyAccessExpression>indexExpression).name).text;
11684
- return getPropertyNameForKnownSymbolName(rightHandSideName);
11685
- }
11686
- return undefined;
11687
- }
11688
-
11689
- /**
11690
- * A proper symbol reference requires the following:
11691
- * 1. The property access denotes a property that exists
11692
- * 2. The expression is of the form Symbol.<identifier>
11693
- * 3. The property access is of the primitive type symbol.
11694
- * 4. Symbol in this context resolves to the global Symbol object
11695
- */
11696
11661
function checkThatExpressionIsProperSymbolReference(expression: Expression, expressionType: Type, reportError: boolean): boolean {
11697
11662
if (expressionType === unknownType) {
11698
11663
// There is already an error, so no need to report one.
0 commit comments