@@ -9877,7 +9877,7 @@ namespace ts {
9877
9877
return false;
9878
9878
}
9879
9879
9880
- function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, cacheSymbol: boolean) {
9880
+ function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, writing: boolean, cacheSymbol: boolean) {
9881
9881
const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined;
9882
9882
const propName = isTypeUsableAsPropertyName(indexType) ?
9883
9883
getPropertyNameFromType(indexType) :
@@ -9928,7 +9928,7 @@ namespace ts {
9928
9928
if (indexInfo) {
9929
9929
const isAssignment = accessExpression && (isAssignmentTarget(accessExpression) || isDeleteTarget(accessExpression));
9930
9930
if (isAssignment && maybeTypeOfKind(originalObjectType, TypeFlags.Instantiable)) {
9931
- error(accessExpression, Diagnostics.Type_0_cannot_be_indexed_by_type_1 , typeToString(originalObjectType ), typeToString(indexType ));
9931
+ error(accessExpression, Diagnostics.Type_0_cannot_be_used_to_index_type_1 , typeToString(indexType ), typeToString(originalObjectType ));
9932
9932
return undefined;
9933
9933
}
9934
9934
if (accessNode && !isTypeAssignableToKind(indexType, TypeFlags.String | TypeFlags.Number)) {
@@ -9938,6 +9938,9 @@ namespace ts {
9938
9938
else if (isAssignment && indexInfo.isReadonly) {
9939
9939
error(accessExpression, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType));
9940
9940
}
9941
+ else if (writing && indexInfo.isReadonly) {
9942
+ return undefined;
9943
+ }
9941
9944
return indexInfo.type;
9942
9945
}
9943
9946
if (indexType.flags & TypeFlags.Never) {
@@ -10081,11 +10084,11 @@ namespace ts {
10081
10084
return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper);
10082
10085
}
10083
10086
10084
- function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression, writing?: boolean ): Type {
10085
- return getIndexedAccessTypeOrUndefined(objectType, indexType, accessNode, writing) || (accessNode ? errorType : unknownType);
10087
+ function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression): Type {
10088
+ return getIndexedAccessTypeOrUndefined(objectType, indexType, accessNode, /* writing*/ false ) || (accessNode ? errorType : unknownType);
10086
10089
}
10087
10090
10088
- function getIndexedAccessTypeOrUndefined(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression, writing?: boolean ): Type | undefined {
10091
+ function getIndexedAccessTypeOrUndefined(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression, writing = false ): Type | undefined {
10089
10092
if (objectType === wildcardType || indexType === wildcardType) {
10090
10093
return wildcardType;
10091
10094
}
@@ -10114,7 +10117,7 @@ namespace ts {
10114
10117
const propTypes: Type[] = [];
10115
10118
let wasMissingProp = false;
10116
10119
for (const t of (<UnionType>indexType).types) {
10117
- const propType = getPropertyTypeForIndexType(objectType, apparentObjectType, t, accessNode, /*cacheSymbol*/ false);
10120
+ const propType = getPropertyTypeForIndexType(objectType, apparentObjectType, t, accessNode, writing, /*cacheSymbol*/ false);
10118
10121
if (propType) {
10119
10122
propTypes.push(propType);
10120
10123
}
@@ -10132,7 +10135,7 @@ namespace ts {
10132
10135
}
10133
10136
return writing ? getIntersectionType(propTypes) : getUnionType(propTypes);
10134
10137
}
10135
- return getPropertyTypeForIndexType(objectType, apparentObjectType, indexType, accessNode, /*cacheSymbol*/ true);
10138
+ return getPropertyTypeForIndexType(objectType, apparentObjectType, indexType, accessNode, writing, /*cacheSymbol*/ true);
10136
10139
}
10137
10140
10138
10141
function getTypeFromIndexedAccessTypeNode(node: IndexedAccessTypeNode) {
@@ -12828,17 +12831,17 @@ namespace ts {
12828
12831
if (indexType.flags & TypeFlags.StructuredOrInstantiable) {
12829
12832
const keyType = getLowerBoundOfKeyType(indexType, /*isIndexType*/ true);
12830
12833
if (keyType !== indexType && !(keyType.flags & TypeFlags.Never)) {
12831
- const targetType = getIndexedAccessType (objectType, keyType, /*accessNode*/ undefined, /*writing*/ true);
12832
- if (result = isRelatedTo(source, targetType, reportErrors)) {
12834
+ const targetType = getIndexedAccessTypeOrUndefined (objectType, keyType, /*accessNode*/ undefined, /*writing*/ true);
12835
+ if (targetType && ( result = isRelatedTo(source, targetType, reportErrors) )) {
12833
12836
return result;
12834
12837
}
12835
12838
}
12836
12839
}
12837
12840
else {
12838
12841
const constraint = getConstraintOfType(objectType);
12839
12842
if (constraint) {
12840
- const targetType = getIndexedAccessType (constraint, indexType, /*accessNode*/ undefined, /*writing*/ true);
12841
- if (result = isRelatedTo(source, targetType, reportErrors)) {
12843
+ const targetType = getIndexedAccessTypeOrUndefined (constraint, indexType, /*accessNode*/ undefined, /*writing*/ true);
12844
+ if (targetType && ( result = isRelatedTo(source, targetType, reportErrors) )) {
12842
12845
return result;
12843
12846
}
12844
12847
}
@@ -19986,7 +19989,7 @@ namespace ts {
19986
19989
}
19987
19990
19988
19991
const effectiveIndexType = isForInVariableForNumericPropertyNames(indexExpression) ? numberType : indexType;
19989
- const indexedAccessType = getIndexedAccessType (objectType, effectiveIndexType, node, isAssignmentTarget(node));
19992
+ const indexedAccessType = getIndexedAccessTypeOrUndefined (objectType, effectiveIndexType, node, isAssignmentTarget(node)) || errorType ;
19990
19993
return checkIndexedAccessIndexType(indexedAccessType, node);
19991
19994
}
19992
19995
0 commit comments