@@ -5697,63 +5697,80 @@ namespace ts {
5697
5697
return links.resolvedType;
5698
5698
}
5699
5699
5700
- function createIndexedAccessType(objectType: Type, keyType : TypeParameter) {
5700
+ function createIndexedAccessType(objectType: Type, indexType : TypeParameter) {
5701
5701
const type = <IndexedAccessType>createType(TypeFlags.IndexedAccess);
5702
5702
type.objectType = objectType;
5703
- type.indexType = keyType ;
5703
+ type.indexType = indexType ;
5704
5704
return type;
5705
5705
}
5706
5706
5707
- function getIndexedAccessTypeForTypeParameter(objectType: Type, keyType : TypeParameter) {
5708
- const indexedAccessTypes = keyType .resolvedIndexedAccessTypes || (keyType .resolvedIndexedAccessTypes = []);
5709
- return indexedAccessTypes[objectType.id] || (indexedAccessTypes[objectType.id] = createIndexedAccessType(objectType, keyType ));
5707
+ function getIndexedAccessTypeForTypeParameter(objectType: Type, indexType : TypeParameter) {
5708
+ const indexedAccessTypes = indexType .resolvedIndexedAccessTypes || (indexType .resolvedIndexedAccessTypes = []);
5709
+ return indexedAccessTypes[objectType.id] || (indexedAccessTypes[objectType.id] = createIndexedAccessType(objectType, indexType ));
5710
5710
}
5711
5711
5712
- function getPropertyTypeForIndexType(objectType: Type, indexType: Type) {
5713
- return indexType.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral | TypeFlags.EnumLiteral) && getTypeOfPropertyOfType(objectType, escapeIdentifier((<LiteralType>indexType).text)) ||
5714
- isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.NumberLike) && getIndexTypeOfType(objectType, IndexKind.Number) ||
5715
- isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.StringLike | TypeFlags.NumberLike) && getIndexTypeOfType(objectType, IndexKind.String) ||
5716
- undefined;
5717
- }
5718
-
5719
- function getIndexedAccessType(objectType: Type, keyType: Type) {
5720
- return keyType.flags & TypeFlags.Any ? anyType :
5721
- keyType.flags & TypeFlags.TypeParameter ? getIndexedAccessTypeForTypeParameter(objectType, <TypeParameter>keyType) :
5722
- mapType(keyType, t => getPropertyTypeForIndexType(objectType, t) || unknownType);
5712
+ function getPropertyTypeForIndexType(objectType: Type, indexType: Type, errorNode?: Node) {
5713
+ if (indexType.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral | TypeFlags.EnumLiteral)) {
5714
+ const propType = getTypeOfPropertyOfType(objectType, escapeIdentifier((<LiteralType>indexType).text));
5715
+ if (propType) {
5716
+ return propType;
5717
+ }
5718
+ }
5719
+ if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.NumberLike)) {
5720
+ const numberIndexType = getIndexTypeOfType(objectType, IndexKind.Number);
5721
+ if (numberIndexType) {
5722
+ return numberIndexType;
5723
+ }
5724
+ }
5725
+ if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.StringLike | TypeFlags.NumberLike)) {
5726
+ const stringIndexType = getIndexTypeOfType(objectType, IndexKind.String);
5727
+ if (stringIndexType) {
5728
+ return stringIndexType;
5729
+ }
5730
+ }
5731
+ if (errorNode) {
5732
+ if (indexType.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) {
5733
+ error(errorNode, Diagnostics.Property_0_does_not_exist_on_type_1, (<LiteralType>indexType).text, typeToString(objectType));
5734
+ }
5735
+ else if (indexType.flags & (TypeFlags.String | TypeFlags.Number)) {
5736
+ error(errorNode, Diagnostics.Type_0_has_no_matching_index_signature_for_type_1, typeToString(objectType), typeToString(indexType));
5737
+ }
5738
+ else {
5739
+ error(errorNode, Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType));
5740
+ }
5741
+ }
5742
+ return unknownType;
5723
5743
}
5724
5744
5725
- function resolveIndexedAccessTypeNode(node: IndexedAccessTypeNode) {
5726
- const objectType = getTypeFromTypeNodeNoAlias(node.objectType);
5727
- const indexType = getTypeFromTypeNodeNoAlias(node.indexType);
5745
+ function getIndexedAccessType(objectType: Type, indexType: Type, errorNode?: Node) {
5728
5746
if (indexType.flags & TypeFlags.TypeParameter) {
5729
5747
if (!isTypeAssignableTo(getConstraintOfTypeParameter(<TypeParameter>indexType), getIndexType(objectType))) {
5730
- error(node.indexType, Diagnostics.Type_0_is_not_constrained_to_keyof_1, typeToString(indexType), typeToString(objectType));
5748
+ if (errorNode) {
5749
+ error(errorNode, Diagnostics.Type_0_is_not_constrained_to_keyof_1, typeToString(indexType), typeToString(objectType));
5750
+ }
5731
5751
return unknownType;
5732
5752
}
5733
- return getIndexedAccessType (objectType, indexType);
5753
+ return getIndexedAccessTypeForTypeParameter (objectType, <TypeParameter> indexType);
5734
5754
}
5735
- const indexTypes = indexType.flags & TypeFlags.Union && !(indexType.flags & TypeFlags.Primitive) ? (<UnionType>indexType).types : [indexType];
5736
- for (const t of indexTypes) {
5737
- if (!getPropertyTypeForIndexType(objectType, t)) {
5738
- if (t.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) {
5739
- error(node.indexType, Diagnostics.Property_0_does_not_exist_on_type_1, (<LiteralType>t).text, typeToString(objectType))
5740
- }
5741
- else if (t.flags & (TypeFlags.String | TypeFlags.Number)) {
5742
- error(node.indexType, Diagnostics.Type_0_has_no_matching_index_signature_for_type_1, typeToString(objectType), typeToString(t));
5743
- }
5744
- else {
5745
- error(node.indexType, Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(t));
5755
+ if (indexType.flags & TypeFlags.Union && !(indexType.flags & TypeFlags.Primitive)) {
5756
+ const propTypes: Type[] = [];
5757
+ for (const t of (<UnionType>indexType).types) {
5758
+ const propType = getPropertyTypeForIndexType(objectType, t, errorNode);
5759
+ if (propType === unknownType) {
5760
+ return unknownType;
5746
5761
}
5747
- return unknownType ;
5762
+ propTypes.push(propType) ;
5748
5763
}
5764
+ return getUnionType(propTypes);
5749
5765
}
5750
- return getIndexedAccessType (objectType, indexType);
5766
+ return getPropertyTypeForIndexType (objectType, indexType, errorNode );
5751
5767
}
5752
5768
5753
5769
function getTypeFromIndexedAccessTypeNode(node: IndexedAccessTypeNode) {
5754
5770
const links = getNodeLinks(node);
5755
5771
if (!links.resolvedType) {
5756
- links.resolvedType = resolveIndexedAccessTypeNode(node);
5772
+ links.resolvedType = getIndexedAccessType(getTypeFromTypeNodeNoAlias(node.objectType),
5773
+ getTypeFromTypeNodeNoAlias(node.indexType), node.indexType);
5757
5774
}
5758
5775
return links.resolvedType;
5759
5776
}
0 commit comments