Remove circularity fallback deferral in getConditionalType (#30470)

This commit is contained in:
Wesley Wigham 2019-03-18 16:35:41 -07:00 committed by GitHub
parent 3127962cd1
commit 9e28a811c5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 31 deletions

View file

@ -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>;
@ -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;
}

View file

@ -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.
@ -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.

View file

@ -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;
@ -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

View file

@ -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'.
~~~~~~~~~~~~~~~~~~~