Skip to content

Commit 9e28a81

Browse files
authored
Remove circularity fallback deferral in getConditionalType (microsoft#30470)
1 parent 3127962 commit 9e28a81

File tree

4 files changed

+27
-31
lines changed

4 files changed

+27
-31
lines changed

src/compiler/checker.ts

+4-17
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ namespace ts {
391391
const intersectionTypes = createMap<IntersectionType>();
392392
const literalTypes = createMap<LiteralType>();
393393
const indexedAccessTypes = createMap<IndexedAccessType>();
394-
const conditionalTypes = createMap<Type | undefined>();
394+
const conditionalTypes = createMap<Type>();
395395
const evolvingArrayTypes: EvolvingArrayType[] = [];
396396
const undefinedProperties = createMap<Symbol>() as UnderscoreEscapedMap<Symbol>;
397397

@@ -10131,24 +10131,11 @@ namespace ts {
1013110131
const trueType = instantiateType(root.trueType, mapper);
1013210132
const falseType = instantiateType(root.falseType, mapper);
1013310133
const instantiationId = `${root.isDistributive ? "d" : ""}${getTypeId(checkType)}>${getTypeId(extendsType)}?${getTypeId(trueType)}:${getTypeId(falseType)}`;
10134-
if (conditionalTypes.has(instantiationId)) {
10135-
const result = conditionalTypes.get(instantiationId);
10136-
if (result !== undefined) {
10137-
return result;
10138-
}
10139-
// Somehow the conditional type depends on itself - usually via `infer` types in the `extends` clause
10140-
// paired with a (potentially deferred) circularly constrained type.
10141-
// The conditional _must_ be deferred.
10142-
const deferred = getDeferredConditionalType(root, mapper, /*combinedMapper*/ undefined, checkType, extendsType, trueType, falseType);
10143-
conditionalTypes.set(instantiationId, deferred);
10144-
return deferred;
10134+
const result = conditionalTypes.get(instantiationId);
10135+
if (result) {
10136+
return result;
1014510137
}
10146-
conditionalTypes.set(instantiationId, undefined);
1014710138
const newResult = getConditionalTypeWorker(root, mapper, checkType, extendsType, trueType, falseType);
10148-
const cachedRecursiveResult = conditionalTypes.get(instantiationId);
10149-
if (cachedRecursiveResult) {
10150-
return cachedRecursiveResult;
10151-
}
1015210139
conditionalTypes.set(instantiationId, newResult);
1015310140
return newResult;
1015410141
}

tests/baselines/reference/circularTypeofWithVarOrFunc.errors.txt

+13-7
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarO
44
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(5,6): error TS2456: Type alias 'typeAlias2' circularly references itself.
55
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(7,18): error TS2577: Return type annotation circularly references itself.
66
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(9,6): error TS2456: Type alias 'typeAlias3' circularly references itself.
7-
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(20,3): error TS2322: Type 'number' is not assignable to type 'ReturnType<(input: Input) => ReturnType<typeof mul>>'.
8-
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(26,20): error TS2322: Type '0' is not assignable to type 'ReturnType<() => ReturnType<typeof f>>'.
7+
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(18,6): error TS2456: Type alias 'R' circularly references itself.
8+
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(19,29): error TS2577: Return type annotation circularly references itself.
9+
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(25,6): error TS2456: Type alias 'R2' circularly references itself.
10+
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(26,15): error TS2577: Return type annotation circularly references itself.
911

1012

11-
==== tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts (8 errors) ====
13+
==== tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts (10 errors) ====
1214
type typeAlias1 = typeof varOfAliasedType1;
1315
~~~~~~~~~~
1416
!!! error TS2456: Type alias 'typeAlias1' circularly references itself.
@@ -39,16 +41,20 @@ tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarO
3941
}
4042

4143
type R = ReturnType<typeof mul>;
44+
~
45+
!!! error TS2456: Type alias 'R' circularly references itself.
4246
function mul(input: Input): R {
47+
~
48+
!!! error TS2577: Return type annotation circularly references itself.
4349
return input.a * input.b;
44-
~~~~~~~~~~~~~~~~~~~~~~~~~
45-
!!! error TS2322: Type 'number' is not assignable to type 'ReturnType<(input: Input) => ReturnType<typeof mul>>'.
4650
}
4751

4852
// Repro from #26104
4953

5054
type R2 = ReturnType<typeof f>;
55+
~~
56+
!!! error TS2456: Type alias 'R2' circularly references itself.
5157
function f(): R2 { return 0; }
52-
~~~~~~~~~
53-
!!! error TS2322: Type '0' is not assignable to type 'ReturnType<() => ReturnType<typeof f>>'.
58+
~~
59+
!!! error TS2577: Return type annotation circularly references itself.
5460

tests/baselines/reference/circularTypeofWithVarOrFunc.types

+6-6
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ interface Input {
3737
}
3838

3939
type R = ReturnType<typeof mul>;
40-
>R : ReturnType<(input: Input) => ReturnType<typeof mul>>
41-
>mul : (input: Input) => ReturnType<typeof mul>
40+
>R : any
41+
>mul : (input: Input) => any
4242

4343
function mul(input: Input): R {
44-
>mul : (input: Input) => ReturnType<typeof mul>
44+
>mul : (input: Input) => any
4545
>input : Input
4646

4747
return input.a * input.b;
@@ -57,10 +57,10 @@ function mul(input: Input): R {
5757
// Repro from #26104
5858

5959
type R2 = ReturnType<typeof f>;
60-
>R2 : ReturnType<() => ReturnType<typeof f>>
61-
>f : () => ReturnType<typeof f>
60+
>R2 : any
61+
>f : () => any
6262

6363
function f(): R2 { return 0; }
64-
>f : () => ReturnType<typeof f>
64+
>f : () => any
6565
>0 : 0
6666

tests/baselines/reference/recursiveResolveTypeMembers.errors.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1+
tests/cases/compiler/recursiveResolveTypeMembers.ts(4,49): error TS2577: Return type annotation circularly references itself.
12
tests/cases/compiler/recursiveResolveTypeMembers.ts(4,58): error TS2304: Cannot find name 'H'.
23
tests/cases/compiler/recursiveResolveTypeMembers.ts(4,62): error TS2574: A rest element type must be an array type.
34
tests/cases/compiler/recursiveResolveTypeMembers.ts(4,79): error TS2304: Cannot find name 'R'.
45

56

6-
==== tests/cases/compiler/recursiveResolveTypeMembers.ts (3 errors) ====
7+
==== tests/cases/compiler/recursiveResolveTypeMembers.ts (4 errors) ====
78
// Repro from #25291
89

910
type PromisedTuple<L extends any[], U = (...args: L) => void> =
1011
U extends (h: infer H, ...args: infer R) => [Promise<H>, ...PromisedTuple<R>] ? [] : []
12+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
13+
!!! error TS2577: Return type annotation circularly references itself.
1114
~
1215
!!! error TS2304: Cannot find name 'H'.
1316
~~~~~~~~~~~~~~~~~~~

0 commit comments

Comments
 (0)