Skip to content

Commit

Permalink
Remove circularity fallback deferral in getConditionalType (microso…
Browse files Browse the repository at this point in the history
  • Loading branch information
weswigham authored Mar 18, 2019
1 parent 3127962 commit 9e28a81
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 31 deletions.
21 changes: 4 additions & 17 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ namespace ts {
const intersectionTypes = createMap<IntersectionType>();
const literalTypes = createMap<LiteralType>();
const indexedAccessTypes = createMap<IndexedAccessType>();
const conditionalTypes = createMap<Type | undefined>();
const conditionalTypes = createMap<Type>();
const evolvingArrayTypes: EvolvingArrayType[] = [];
const undefinedProperties = createMap<Symbol>() as UnderscoreEscapedMap<Symbol>;

Expand Down Expand Up @@ -10131,24 +10131,11 @@ namespace ts {
const trueType = instantiateType(root.trueType, mapper);
const falseType = instantiateType(root.falseType, mapper);
const instantiationId = `${root.isDistributive ? "d" : ""}${getTypeId(checkType)}>${getTypeId(extendsType)}?${getTypeId(trueType)}:${getTypeId(falseType)}`;
if (conditionalTypes.has(instantiationId)) {
const result = conditionalTypes.get(instantiationId);
if (result !== undefined) {
return result;
}
// Somehow the conditional type depends on itself - usually via `infer` types in the `extends` clause
// paired with a (potentially deferred) circularly constrained type.
// The conditional _must_ be deferred.
const deferred = getDeferredConditionalType(root, mapper, /*combinedMapper*/ undefined, checkType, extendsType, trueType, falseType);
conditionalTypes.set(instantiationId, deferred);
return deferred;
const result = conditionalTypes.get(instantiationId);
if (result) {
return result;
}
conditionalTypes.set(instantiationId, undefined);
const newResult = getConditionalTypeWorker(root, mapper, checkType, extendsType, trueType, falseType);
const cachedRecursiveResult = conditionalTypes.get(instantiationId);
if (cachedRecursiveResult) {
return cachedRecursiveResult;
}
conditionalTypes.set(instantiationId, newResult);
return newResult;
}
Expand Down
20 changes: 13 additions & 7 deletions tests/baselines/reference/circularTypeofWithVarOrFunc.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarO
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(5,6): error TS2456: Type alias 'typeAlias2' circularly references itself.
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(7,18): error TS2577: Return type annotation circularly references itself.
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(9,6): error TS2456: Type alias 'typeAlias3' circularly references itself.
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>>'.
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(26,20): error TS2322: Type '0' is not assignable to type 'ReturnType<() => ReturnType<typeof f>>'.
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(18,6): error TS2456: Type alias 'R' circularly references itself.
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(19,29): error TS2577: Return type annotation circularly references itself.
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(25,6): error TS2456: Type alias 'R2' circularly references itself.
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(26,15): error TS2577: Return type annotation circularly references itself.


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

type R = ReturnType<typeof mul>;
~
!!! error TS2456: Type alias 'R' circularly references itself.
function mul(input: Input): R {
~
!!! error TS2577: Return type annotation circularly references itself.
return input.a * input.b;
~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'ReturnType<(input: Input) => ReturnType<typeof mul>>'.
}

// Repro from #26104

type R2 = ReturnType<typeof f>;
~~
!!! error TS2456: Type alias 'R2' circularly references itself.
function f(): R2 { return 0; }
~~~~~~~~~
!!! error TS2322: Type '0' is not assignable to type 'ReturnType<() => ReturnType<typeof f>>'.
~~
!!! error TS2577: Return type annotation circularly references itself.

12 changes: 6 additions & 6 deletions tests/baselines/reference/circularTypeofWithVarOrFunc.types
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ interface Input {
}

type R = ReturnType<typeof mul>;
>R : ReturnType<(input: Input) => ReturnType<typeof mul>>
>mul : (input: Input) => ReturnType<typeof mul>
>R : any
>mul : (input: Input) => any

function mul(input: Input): R {
>mul : (input: Input) => ReturnType<typeof mul>
>mul : (input: Input) => any
>input : Input

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

type R2 = ReturnType<typeof f>;
>R2 : ReturnType<() => ReturnType<typeof f>>
>f : () => ReturnType<typeof f>
>R2 : any
>f : () => any

function f(): R2 { return 0; }
>f : () => ReturnType<typeof f>
>f : () => any
>0 : 0

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


==== tests/cases/compiler/recursiveResolveTypeMembers.ts (3 errors) ====
==== tests/cases/compiler/recursiveResolveTypeMembers.ts (4 errors) ====
// Repro from #25291

type PromisedTuple<L extends any[], U = (...args: L) => void> =
U extends (h: infer H, ...args: infer R) => [Promise<H>, ...PromisedTuple<R>] ? [] : []
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2577: Return type annotation circularly references itself.
~
!!! error TS2304: Cannot find name 'H'.
~~~~~~~~~~~~~~~~~~~
Expand Down

0 comments on commit 9e28a81

Please sign in to comment.