Skip to content

Commit 88b7d53

Browse files
authored
Merge pull request #12515 from Microsoft/fixMappedTypeInference
Include mapped types in type inference infinite recursion check
2 parents 283c50c + d1393a6 commit 88b7d53

File tree

5 files changed

+93
-17
lines changed

5 files changed

+93
-17
lines changed

src/compiler/checker.ts

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8590,19 +8590,6 @@ namespace ts {
85908590
}
85918591
}
85928592
else {
8593-
if (getObjectFlags(target) & ObjectFlags.Mapped) {
8594-
const constraintType = getConstraintTypeFromMappedType(<MappedType>target);
8595-
if (getObjectFlags(source) & ObjectFlags.Mapped) {
8596-
inferFromTypes(getConstraintTypeFromMappedType(<MappedType>source), constraintType);
8597-
inferFromTypes(getTemplateTypeFromMappedType(<MappedType>source), getTemplateTypeFromMappedType(<MappedType>target));
8598-
return;
8599-
}
8600-
if (constraintType.flags & TypeFlags.TypeParameter) {
8601-
inferFromTypes(getIndexType(source), constraintType);
8602-
inferFromTypes(getUnionType(map(getPropertiesOfType(source), getTypeOfSymbol)), getTemplateTypeFromMappedType(<MappedType>target));
8603-
return;
8604-
}
8605-
}
86068593
source = getApparentType(source);
86078594
if (source.flags & TypeFlags.Object) {
86088595
if (isInProcess(source, target)) {
@@ -8623,15 +8610,32 @@ namespace ts {
86238610
sourceStack[depth] = source;
86248611
targetStack[depth] = target;
86258612
depth++;
8626-
inferFromProperties(source, target);
8627-
inferFromSignatures(source, target, SignatureKind.Call);
8628-
inferFromSignatures(source, target, SignatureKind.Construct);
8629-
inferFromIndexTypes(source, target);
8613+
inferFromObjectTypes(source, target);
86308614
depth--;
86318615
}
86328616
}
86338617
}
86348618

8619+
function inferFromObjectTypes(source: Type, target: Type) {
8620+
if (getObjectFlags(target) & ObjectFlags.Mapped) {
8621+
const constraintType = getConstraintTypeFromMappedType(<MappedType>target);
8622+
if (getObjectFlags(source) & ObjectFlags.Mapped) {
8623+
inferFromTypes(getConstraintTypeFromMappedType(<MappedType>source), constraintType);
8624+
inferFromTypes(getTemplateTypeFromMappedType(<MappedType>source), getTemplateTypeFromMappedType(<MappedType>target));
8625+
return;
8626+
}
8627+
if (constraintType.flags & TypeFlags.TypeParameter) {
8628+
inferFromTypes(getIndexType(source), constraintType);
8629+
inferFromTypes(getUnionType(map(getPropertiesOfType(source), getTypeOfSymbol)), getTemplateTypeFromMappedType(<MappedType>target));
8630+
return;
8631+
}
8632+
}
8633+
inferFromProperties(source, target);
8634+
inferFromSignatures(source, target, SignatureKind.Call);
8635+
inferFromSignatures(source, target, SignatureKind.Construct);
8636+
inferFromIndexTypes(source, target);
8637+
}
8638+
86358639
function inferFromProperties(source: Type, target: Type) {
86368640
const properties = getPropertiesOfObjectType(target);
86378641
for (const targetProp of properties) {
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//// [mappedTypeInferenceCircularity.ts]
2+
// Repro from #12511
3+
4+
type HTML = { [K in 'div']: Block<HTML> };
5+
type Block<P> = <T>(func: HTML) => {};
6+
7+
declare var h: HTML;
8+
h.div(h);
9+
10+
//// [mappedTypeInferenceCircularity.js]
11+
// Repro from #12511
12+
h.div(h);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
=== tests/cases/compiler/mappedTypeInferenceCircularity.ts ===
2+
// Repro from #12511
3+
4+
type HTML = { [K in 'div']: Block<HTML> };
5+
>HTML : Symbol(HTML, Decl(mappedTypeInferenceCircularity.ts, 0, 0))
6+
>K : Symbol(K, Decl(mappedTypeInferenceCircularity.ts, 2, 15))
7+
>Block : Symbol(Block, Decl(mappedTypeInferenceCircularity.ts, 2, 42))
8+
>HTML : Symbol(HTML, Decl(mappedTypeInferenceCircularity.ts, 0, 0))
9+
10+
type Block<P> = <T>(func: HTML) => {};
11+
>Block : Symbol(Block, Decl(mappedTypeInferenceCircularity.ts, 2, 42))
12+
>P : Symbol(P, Decl(mappedTypeInferenceCircularity.ts, 3, 11))
13+
>T : Symbol(T, Decl(mappedTypeInferenceCircularity.ts, 3, 17))
14+
>func : Symbol(func, Decl(mappedTypeInferenceCircularity.ts, 3, 20))
15+
>HTML : Symbol(HTML, Decl(mappedTypeInferenceCircularity.ts, 0, 0))
16+
17+
declare var h: HTML;
18+
>h : Symbol(h, Decl(mappedTypeInferenceCircularity.ts, 5, 11))
19+
>HTML : Symbol(HTML, Decl(mappedTypeInferenceCircularity.ts, 0, 0))
20+
21+
h.div(h);
22+
>h.div : Symbol(div)
23+
>h : Symbol(h, Decl(mappedTypeInferenceCircularity.ts, 5, 11))
24+
>div : Symbol(div)
25+
>h : Symbol(h, Decl(mappedTypeInferenceCircularity.ts, 5, 11))
26+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
=== tests/cases/compiler/mappedTypeInferenceCircularity.ts ===
2+
// Repro from #12511
3+
4+
type HTML = { [K in 'div']: Block<HTML> };
5+
>HTML : HTML
6+
>K : K
7+
>Block : Block<P>
8+
>HTML : HTML
9+
10+
type Block<P> = <T>(func: HTML) => {};
11+
>Block : Block<P>
12+
>P : P
13+
>T : T
14+
>func : HTML
15+
>HTML : HTML
16+
17+
declare var h: HTML;
18+
>h : HTML
19+
>HTML : HTML
20+
21+
h.div(h);
22+
>h.div(h) : {}
23+
>h.div : Block<HTML>
24+
>h : HTML
25+
>div : Block<HTML>
26+
>h : HTML
27+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Repro from #12511
2+
3+
type HTML = { [K in 'div']: Block<HTML> };
4+
type Block<P> = <T>(func: HTML) => {};
5+
6+
declare var h: HTML;
7+
h.div(h);

0 commit comments

Comments
 (0)