Skip to content

Commit 63d746b

Browse files
committed
Higher order inference for mapped, index and lookup types
1 parent eb80799 commit 63d746b

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

src/compiler/checker.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10386,7 +10386,7 @@ namespace ts {
1038610386
// results for union and intersection types for performance reasons.
1038710387
function couldContainTypeVariables(type: Type): boolean {
1038810388
const objectFlags = getObjectFlags(type);
10389-
return !!(type.flags & TypeFlags.TypeVariable ||
10389+
return !!(type.flags & (TypeFlags.TypeVariable | TypeFlags.Index) ||
1039010390
objectFlags & ObjectFlags.Reference && forEach((<TypeReference>type).typeArguments, couldContainTypeVariables) ||
1039110391
objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class) ||
1039210392
objectFlags & ObjectFlags.Mapped ||
@@ -10554,6 +10554,13 @@ namespace ts {
1055410554
inferFromTypes(sourceTypes[i], targetTypes[i]);
1055510555
}
1055610556
}
10557+
else if (source.flags & TypeFlags.Index && target.flags & TypeFlags.Index) {
10558+
inferFromTypes((<IndexType>source).type, (<IndexType>target).type);
10559+
}
10560+
else if (source.flags & TypeFlags.IndexedAccess && target.flags & TypeFlags.IndexedAccess) {
10561+
inferFromTypes((<IndexedAccessType>source).objectType, (<IndexedAccessType>target).objectType);
10562+
inferFromTypes((<IndexedAccessType>source).indexType, (<IndexedAccessType>target).indexType);
10563+
}
1055710564
else if (target.flags & TypeFlags.UnionOrIntersection) {
1055810565
const targetTypes = (<UnionOrIntersectionType>target).types;
1055910566
let typeVariableCount = 0;
@@ -10627,6 +10634,12 @@ namespace ts {
1062710634
}
1062810635

1062910636
function inferFromObjectTypes(source: Type, target: Type) {
10637+
if (isGenericMappedType(source) && isGenericMappedType(target)) {
10638+
// The source and target types are generic types { [P in S]: X } and { [P in T]: Y }, so we infer
10639+
// from S to T and from X to Y.
10640+
inferFromTypes(getConstraintTypeFromMappedType(<MappedType>source), getConstraintTypeFromMappedType(<MappedType>target));
10641+
inferFromTypes(getTemplateTypeFromMappedType(<MappedType>source), getTemplateTypeFromMappedType(<MappedType>target));
10642+
}
1063010643
if (getObjectFlags(target) & ObjectFlags.Mapped) {
1063110644
const constraintType = getConstraintTypeFromMappedType(<MappedType>target);
1063210645
if (constraintType.flags & TypeFlags.Index) {

0 commit comments

Comments
 (0)