@@ -7488,15 +7488,18 @@ namespace ts {
7488
7488
}
7489
7489
7490
7490
function getConstraintFromIndexedAccess(type: IndexedAccessType) {
7491
- const objectType = getConstraintOfType(type.objectType) || type.objectType ;
7492
- if (objectType !== type.objectType ) {
7493
- const constraint = getIndexedAccessTypeOrUndefined(objectType, type.indexType );
7494
- if (constraint ) {
7495
- return constraint ;
7491
+ const indexConstraint = getConstraintOfType(type.indexType) ;
7492
+ if (indexConstraint && indexConstraint !== type.indexType ) {
7493
+ const indexedAccess = getIndexedAccessTypeOrUndefined(type. objectType, indexConstraint );
7494
+ if (indexedAccess ) {
7495
+ return indexedAccess ;
7496
7496
}
7497
7497
}
7498
- const baseConstraint = getBaseConstraintOfType(type);
7499
- return baseConstraint && baseConstraint !== type ? baseConstraint : undefined;
7498
+ const objectConstraint = getConstraintOfType(type.objectType);
7499
+ if (objectConstraint && objectConstraint !== type.objectType) {
7500
+ return getIndexedAccessTypeOrUndefined(objectConstraint, type.indexType);
7501
+ }
7502
+ return undefined;
7500
7503
}
7501
7504
7502
7505
function getDefaultConstraintOfConditionalType(type: ConditionalType) {
@@ -9920,14 +9923,14 @@ namespace ts {
9920
9923
if (objectType.flags & (TypeFlags.Any | TypeFlags.Never)) {
9921
9924
return objectType;
9922
9925
}
9923
- const isAssignment = accessExpression && (isAssignmentTarget(accessExpression) || isDeleteTarget(accessExpression));
9924
- if (isAssignment && maybeTypeOfKind(originalObjectType, TypeFlags.Instantiable)) {
9925
- error(accessExpression, Diagnostics.Type_0_cannot_be_indexed_by_type_1, typeToString(originalObjectType), typeToString(indexType));
9926
- return undefined;
9927
- }
9928
9926
const indexInfo = isTypeAssignableToKind(indexType, TypeFlags.NumberLike) && getIndexInfoOfType(objectType, IndexKind.Number) ||
9929
9927
getIndexInfoOfType(objectType, IndexKind.String);
9930
9928
if (indexInfo) {
9929
+ const isAssignment = accessExpression && (isAssignmentTarget(accessExpression) || isDeleteTarget(accessExpression));
9930
+ if (isAssignment && maybeTypeOfKind(originalObjectType, TypeFlags.Instantiable)) {
9931
+ error(accessExpression, Diagnostics.Type_0_cannot_be_indexed_by_type_1, typeToString(originalObjectType), typeToString(indexType));
9932
+ return undefined;
9933
+ }
9931
9934
if (accessNode && !isTypeAssignableToKind(indexType, TypeFlags.String | TypeFlags.Number)) {
9932
9935
const indexNode = getIndexNodeForAccessExpression(accessNode);
9933
9936
error(indexNode, Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType));
@@ -12820,7 +12823,7 @@ namespace ts {
12820
12823
// A type S is related to a type T[K], where T and K aren't both type variables, if S is related to C,
12821
12824
// where C is the base constraint of T[K]
12822
12825
if (relation !== identityRelation) {
12823
- const objectType = (<IndexedAccessType>target).objectType
12826
+ const objectType = (<IndexedAccessType>target).objectType;
12824
12827
const indexType = (<IndexedAccessType>target).indexType;
12825
12828
if (indexType.flags & TypeFlags.StructuredOrInstantiable) {
12826
12829
const keyType = getLowerBoundOfKeyType(indexType, /*isIndexType*/ true);
@@ -12885,23 +12888,25 @@ namespace ts {
12885
12888
return result;
12886
12889
}
12887
12890
}
12888
- const constraint = getConstraintOfType(<TypeVariable>source);
12889
- if (!constraint || (source.flags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.Any)) {
12890
- // A type variable with no constraint is not related to the non-primitive object type.
12891
- if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive))) {
12891
+ else {
12892
+ const constraint = getConstraintOfType(<TypeVariable>source);
12893
+ if (!constraint || (source.flags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.Any)) {
12894
+ // A type variable with no constraint is not related to the non-primitive object type.
12895
+ if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive))) {
12896
+ errorInfo = saveErrorInfo;
12897
+ return result;
12898
+ }
12899
+ }
12900
+ // hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed
12901
+ else if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, isIntersectionConstituent)) {
12892
12902
errorInfo = saveErrorInfo;
12893
12903
return result;
12894
12904
}
12895
- }
12896
- // hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed
12897
- else if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, isIntersectionConstituent)) {
12905
+ // slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example
12906
+ else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, reportErrors, /*headMessage*/ undefined, isIntersectionConstituent)) {
12898
12907
errorInfo = saveErrorInfo;
12899
12908
return result;
12900
- }
12901
- // slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example
12902
- else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, reportErrors, /*headMessage*/ undefined, isIntersectionConstituent)) {
12903
- errorInfo = saveErrorInfo;
12904
- return result;
12909
+ }
12905
12910
}
12906
12911
}
12907
12912
else if (source.flags & TypeFlags.Index) {
0 commit comments