Skip to content

Commit f483738

Browse files
committed
Type { [P in K]: E }[X] has constraint E with X substutited for P
1 parent a3d23d3 commit f483738

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

src/compiler/checker.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11754,6 +11754,11 @@ namespace ts {
1175411754
}
1175511755

1175611756
function getConstraintFromIndexedAccess(type: IndexedAccessType) {
11757+
if (isMappedTypeGenericIndexedAccess(type)) {
11758+
// For indexed access types of the form { [P in K]: E }[X], where K is non-generic and X is generic,
11759+
// we substitute an instantiation of E where P is replaced with X.
11760+
return substituteIndexedMappedType(type.objectType as MappedType, type.indexType);
11761+
}
1175711762
const indexConstraint = getSimplifiedTypeOrConstraint(type.indexType);
1175811763
if (indexConstraint && indexConstraint !== type.indexType) {
1175911764
const indexedAccess = getIndexedAccessTypeOrUndefined(type.objectType, indexConstraint, type.accessFlags);
@@ -11967,6 +11972,11 @@ namespace ts {
1196711972
return constraint ? getStringMappingType((t as StringMappingType).symbol, constraint) : stringType;
1196811973
}
1196911974
if (t.flags & TypeFlags.IndexedAccess) {
11975+
if (isMappedTypeGenericIndexedAccess(t)) {
11976+
// For indexed access types of the form { [P in K]: E }[X], where K is non-generic and X is generic,
11977+
// we substitute an instantiation of E where P is replaced with X.
11978+
return getBaseConstraint(substituteIndexedMappedType((t as IndexedAccessType).objectType as MappedType, (t as IndexedAccessType).indexType));
11979+
}
1197011980
const baseObjectType = getBaseConstraint((t as IndexedAccessType).objectType);
1197111981
const baseIndexType = getBaseConstraint((t as IndexedAccessType).indexType);
1197211982
const baseIndexedAccess = baseObjectType && baseIndexType && getIndexedAccessTypeOrUndefined(baseObjectType, baseIndexType, (t as IndexedAccessType).accessFlags);
@@ -12060,13 +12070,7 @@ namespace ts {
1206012070
* type itself.
1206112071
*/
1206212072
function getApparentType(type: Type): Type {
12063-
// We obtain the base constraint for all instantiable types, except indexed access types of the form
12064-
// { [P in K]: E }[X], where K is non-generic and X is generic. For those types, we instead substitute an
12065-
// instantiation of E where P is replaced with X. We do this because getBaseConstraintOfType directly
12066-
// lowers to an instantiation where X's constraint is substituted for X, which isn't always desirable.
12067-
const t = !(type.flags & TypeFlags.Instantiable) ? type :
12068-
isMappedTypeGenericIndexedAccess(type) ? substituteIndexedMappedType((type as IndexedAccessType).objectType as MappedType, (type as IndexedAccessType).indexType) :
12069-
getBaseConstraintOfType(type) || unknownType;
12073+
const t = !(type.flags & TypeFlags.Instantiable) ? type : getBaseConstraintOfType(type) || unknownType;
1207012074
return getObjectFlags(t) & ObjectFlags.Mapped ? getApparentTypeOfMappedType(t as MappedType) :
1207112075
t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(t as IntersectionType) :
1207212076
t.flags & TypeFlags.StringLike ? globalStringType :

0 commit comments

Comments
 (0)