Fix mapped type instantiation circularity (#46586)

* Don't obtain constraint if doing so would cause circularity

* Add regression test

* Address CR feedback
This commit is contained in:
Anders Hejlsberg 2021-10-29 14:01:27 -07:00 committed by GitHub
parent 28e3cd3a80
commit b0ab2a54bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 77 additions and 4 deletions

View File

@ -16604,7 +16604,8 @@ namespace ts {
if (t.flags & (TypeFlags.AnyOrUnknown | TypeFlags.InstantiableNonPrimitive | TypeFlags.Object | TypeFlags.Intersection) && t !== wildcardType && !isErrorType(t)) {
if (!type.declaration.nameType) {
let constraint;
if (isArrayType(t) || (t.flags & TypeFlags.Any) && (constraint = getConstraintOfTypeParameter(typeVariable)) && everyType(constraint, or(isArrayType, isTupleType))) {
if (isArrayType(t) || t.flags & TypeFlags.Any && findResolutionCycleStartIndex(typeVariable, TypeSystemPropertyName.ImmediateBaseConstraint) < 0 &&
(constraint = getConstraintOfTypeParameter(typeVariable)) && everyType(constraint, or(isArrayType, isTupleType))) {
return instantiateMappedArrayType(t, type, prependTypeMapping(typeVariable, t, mapper));
}
if (isGenericTupleType(t)) {

View File

@ -67,4 +67,14 @@ tests/cases/conformance/types/mapped/mappedTypeWithAny.ts(53,5): error TS2322: T
let def: [any, any] = stringifyPair(void 0 as any);
~~~
!!! error TS2322: Type 'string[]' is not assignable to type '[any, any]'.
!!! error TS2322: Target requires 2 element(s) but source may have fewer.
!!! error TS2322: Target requires 2 element(s) but source may have fewer.
// Repro from #46582
type Evolvable<E extends Evolver> = {
[P in keyof E]: never;
};
type Evolver<T extends Evolvable<any> = any> = {
[key in keyof Partial<T>]: never;
};

View File

@ -51,7 +51,17 @@ declare function stringifyArray<T extends readonly any[]>(arr: T): { -readonly [
let abc: any[] = stringifyArray(void 0 as any);
declare function stringifyPair<T extends readonly [any, any]>(arr: T): { -readonly [K in keyof T]: string };
let def: [any, any] = stringifyPair(void 0 as any);
let def: [any, any] = stringifyPair(void 0 as any);
// Repro from #46582
type Evolvable<E extends Evolver> = {
[P in keyof E]: never;
};
type Evolver<T extends Evolvable<any> = any> = {
[key in keyof Partial<T>]: never;
};
//// [mappedTypeWithAny.js]
"use strict";
@ -110,3 +120,9 @@ declare function stringifyPair<T extends readonly [any, any]>(arr: T): {
-readonly [K in keyof T]: string;
};
declare let def: [any, any];
declare type Evolvable<E extends Evolver> = {
[P in keyof E]: never;
};
declare type Evolver<T extends Evolvable<any> = any> = {
[key in keyof Partial<T>]: never;
};

View File

@ -151,3 +151,27 @@ let def: [any, any] = stringifyPair(void 0 as any);
>def : Symbol(def, Decl(mappedTypeWithAny.ts, 52, 3))
>stringifyPair : Symbol(stringifyPair, Decl(mappedTypeWithAny.ts, 49, 47))
// Repro from #46582
type Evolvable<E extends Evolver> = {
>Evolvable : Symbol(Evolvable, Decl(mappedTypeWithAny.ts, 52, 51))
>E : Symbol(E, Decl(mappedTypeWithAny.ts, 56, 15))
>Evolver : Symbol(Evolver, Decl(mappedTypeWithAny.ts, 58, 2))
[P in keyof E]: never;
>P : Symbol(P, Decl(mappedTypeWithAny.ts, 57, 3))
>E : Symbol(E, Decl(mappedTypeWithAny.ts, 56, 15))
};
type Evolver<T extends Evolvable<any> = any> = {
>Evolver : Symbol(Evolver, Decl(mappedTypeWithAny.ts, 58, 2))
>T : Symbol(T, Decl(mappedTypeWithAny.ts, 59, 13))
>Evolvable : Symbol(Evolvable, Decl(mappedTypeWithAny.ts, 52, 51))
[key in keyof Partial<T>]: never;
>key : Symbol(key, Decl(mappedTypeWithAny.ts, 60, 3))
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypeWithAny.ts, 59, 13))
};

View File

@ -125,3 +125,16 @@ let def: [any, any] = stringifyPair(void 0 as any);
>void 0 : undefined
>0 : 0
// Repro from #46582
type Evolvable<E extends Evolver> = {
>Evolvable : Evolvable<E>
[P in keyof E]: never;
};
type Evolver<T extends Evolvable<any> = any> = {
>Evolver : Evolver<T>
[key in keyof Partial<T>]: never;
};

View File

@ -53,4 +53,13 @@ declare function stringifyArray<T extends readonly any[]>(arr: T): { -readonly [
let abc: any[] = stringifyArray(void 0 as any);
declare function stringifyPair<T extends readonly [any, any]>(arr: T): { -readonly [K in keyof T]: string };
let def: [any, any] = stringifyPair(void 0 as any);
let def: [any, any] = stringifyPair(void 0 as any);
// Repro from #46582
type Evolvable<E extends Evolver> = {
[P in keyof E]: never;
};
type Evolver<T extends Evolvable<any> = any> = {
[key in keyof Partial<T>]: never;
};