1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
=== tests/cases/compiler/deferredLookupTypeResolution.ts ===
// Repro from #17456
type StringContains<S extends string, L extends string> = (
>StringContains : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L]
{ [K in S]: 'true' } &
{ [key: string]: 'false' }
>key : string
)[L]
type ObjectHasKey<O, L extends string> = StringContains<Extract<keyof O, string>, L>
>ObjectHasKey : ({ [K in Extract<keyof O, string>]: "true"; } & { [key: string]: "false"; })[L]
type First<T> = ObjectHasKey<T, '0'>; // Should be deferred
>First : ({ [K in Extract<keyof T, string>]: "true"; } & { [key: string]: "false"; })["0"]
type T1 = ObjectHasKey<{ a: string }, 'a'>; // 'true'
>T1 : "true"
>a : string
type T2 = ObjectHasKey<{ a: string }, 'b'>; // 'false'
>T2 : "false"
>a : string
// Verify that mapped type isn't eagerly resolved in type-to-string operation
declare function f1<A extends string, B extends string>(a: A, b: B): { [P in A | B]: any };
>f1 : <A extends string, B extends string>(a: A, b: B) => { [P in A | B]: any; }
>a : A
>b : B
function f2<A extends string>(a: A) {
>f2 : <A extends string>(a: A) => { [P in A | "x"]: any; }
>a : A
return f1(a, 'x');
>f1(a, 'x') : { [P in A | "x"]: any; }
>f1 : <A extends string, B extends string>(a: A, b: B) => { [P in A | B]: any; }
>a : A
>'x' : "x"
}
function f3(x: 'a' | 'b') {
>f3 : (x: "a" | "b") => { a: any; b: any; x: any; }
>x : "a" | "b"
return f2(x);
>f2(x) : { a: any; b: any; x: any; }
>f2 : <A extends string>(a: A) => { [P in A | "x"]: any; }
>x : "a" | "b"
}
|