TypeScript/tests/baselines/reference/mappedTypeAsClauses.symbols
Anders Hejlsberg 73736d9b84
Fix logic for determining whether to simplify keyof on mapped types (#44042)
* Fix logic for determining whether to simplify keyof on mapped types

* Add regression test

* Improve hasDistributiveNameType check

* Add more tests

* Address code review feedback

* Add more tests
2021-05-19 13:43:22 -07:00

543 lines
24 KiB
Plaintext

=== tests/cases/conformance/types/mapped/mappedTypeAsClauses.ts ===
// Mapped type 'as N' clauses
type Getters<T> = { [P in keyof T & string as `get${Capitalize<P>}`]: () => T[P] };
>Getters : Symbol(Getters, Decl(mappedTypeAsClauses.ts, 0, 0))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 2, 13))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 2, 21))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 2, 13))
>Capitalize : Symbol(Capitalize, Decl(lib.es5.d.ts, --, --))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 2, 21))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 2, 13))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 2, 21))
type TG1 = Getters<{ foo: string, bar: number, baz: { z: boolean } }>;
>TG1 : Symbol(TG1, Decl(mappedTypeAsClauses.ts, 2, 83))
>Getters : Symbol(Getters, Decl(mappedTypeAsClauses.ts, 0, 0))
>foo : Symbol(foo, Decl(mappedTypeAsClauses.ts, 3, 20))
>bar : Symbol(bar, Decl(mappedTypeAsClauses.ts, 3, 33))
>baz : Symbol(baz, Decl(mappedTypeAsClauses.ts, 3, 46))
>z : Symbol(z, Decl(mappedTypeAsClauses.ts, 3, 53))
// Mapped type with 'as N' clause has no constraint on 'in T' clause
type PropDef<K extends keyof any, T> = { name: K, type: T };
>PropDef : Symbol(PropDef, Decl(mappedTypeAsClauses.ts, 3, 70))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 7, 13))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 7, 33))
>name : Symbol(name, Decl(mappedTypeAsClauses.ts, 7, 40))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 7, 13))
>type : Symbol(type, Decl(mappedTypeAsClauses.ts, 7, 49))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 7, 33))
type TypeFromDefs<T extends PropDef<keyof any, any>> = { [P in T as P['name']]: P['type'] };
>TypeFromDefs : Symbol(TypeFromDefs, Decl(mappedTypeAsClauses.ts, 7, 60))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 9, 18))
>PropDef : Symbol(PropDef, Decl(mappedTypeAsClauses.ts, 3, 70))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 9, 58))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 9, 18))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 9, 58))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 9, 58))
type TP1 = TypeFromDefs<{ name: 'a', type: string } | { name: 'b', type: number } | { name: 'a', type: boolean }>;
>TP1 : Symbol(TP1, Decl(mappedTypeAsClauses.ts, 9, 92))
>TypeFromDefs : Symbol(TypeFromDefs, Decl(mappedTypeAsClauses.ts, 7, 60))
>name : Symbol(name, Decl(mappedTypeAsClauses.ts, 11, 25))
>type : Symbol(type, Decl(mappedTypeAsClauses.ts, 11, 36))
>name : Symbol(name, Decl(mappedTypeAsClauses.ts, 11, 55))
>type : Symbol(type, Decl(mappedTypeAsClauses.ts, 11, 66))
>name : Symbol(name, Decl(mappedTypeAsClauses.ts, 11, 85))
>type : Symbol(type, Decl(mappedTypeAsClauses.ts, 11, 96))
// No array or tuple type mapping when 'as N' clause present
type TA1 = Getters<string[]>;
>TA1 : Symbol(TA1, Decl(mappedTypeAsClauses.ts, 11, 114))
>Getters : Symbol(Getters, Decl(mappedTypeAsClauses.ts, 0, 0))
type TA2 = Getters<[number, boolean]>;
>TA2 : Symbol(TA2, Decl(mappedTypeAsClauses.ts, 15, 29))
>Getters : Symbol(Getters, Decl(mappedTypeAsClauses.ts, 0, 0))
// Filtering using 'as N' clause
type Methods<T> = { [P in keyof T as T[P] extends Function ? P : never]: T[P] };
>Methods : Symbol(Methods, Decl(mappedTypeAsClauses.ts, 16, 38))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 20, 13))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 20, 21))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 20, 13))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 20, 13))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 20, 21))
>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 20, 21))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 20, 13))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 20, 21))
type TM1 = Methods<{ foo(): number, bar(x: string): boolean, baz: string | number }>;
>TM1 : Symbol(TM1, Decl(mappedTypeAsClauses.ts, 20, 80))
>Methods : Symbol(Methods, Decl(mappedTypeAsClauses.ts, 16, 38))
>foo : Symbol(foo, Decl(mappedTypeAsClauses.ts, 21, 20))
>bar : Symbol(bar, Decl(mappedTypeAsClauses.ts, 21, 35))
>x : Symbol(x, Decl(mappedTypeAsClauses.ts, 21, 40))
>baz : Symbol(baz, Decl(mappedTypeAsClauses.ts, 21, 60))
// Mapping to multiple names using 'as N' clause
type DoubleProp<T> = { [P in keyof T & string as `${P}1` | `${P}2`]: T[P] }
>DoubleProp : Symbol(DoubleProp, Decl(mappedTypeAsClauses.ts, 21, 85))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 25, 16))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 25, 24))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 25, 16))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 25, 24))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 25, 24))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 25, 16))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 25, 24))
type TD1 = DoubleProp<{ a: string, b: number }>; // { a1: string, a2: string, b1: number, b2: number }
>TD1 : Symbol(TD1, Decl(mappedTypeAsClauses.ts, 25, 75))
>DoubleProp : Symbol(DoubleProp, Decl(mappedTypeAsClauses.ts, 21, 85))
>a : Symbol(a, Decl(mappedTypeAsClauses.ts, 26, 23))
>b : Symbol(b, Decl(mappedTypeAsClauses.ts, 26, 34))
type TD2 = keyof TD1; // 'a1' | 'a2' | 'b1' | 'b2'
>TD2 : Symbol(TD2, Decl(mappedTypeAsClauses.ts, 26, 48))
>TD1 : Symbol(TD1, Decl(mappedTypeAsClauses.ts, 25, 75))
type TD3<U> = keyof DoubleProp<U>; // `${keyof U & string}1` | `${keyof U & string}2`
>TD3 : Symbol(TD3, Decl(mappedTypeAsClauses.ts, 27, 21))
>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 28, 9))
>DoubleProp : Symbol(DoubleProp, Decl(mappedTypeAsClauses.ts, 21, 85))
>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 28, 9))
// Repro from #40619
type Lazyify<T> = {
>Lazyify : Symbol(Lazyify, Decl(mappedTypeAsClauses.ts, 28, 34))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 32, 13))
[K in keyof T as `get${Capitalize<K & string>}`]: () => T[K]
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 33, 5))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 32, 13))
>Capitalize : Symbol(Capitalize, Decl(lib.es5.d.ts, --, --))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 33, 5))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 32, 13))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 33, 5))
};
interface Person {
>Person : Symbol(Person, Decl(mappedTypeAsClauses.ts, 34, 2))
readonly name: string;
>name : Symbol(Person.name, Decl(mappedTypeAsClauses.ts, 36, 18))
age: number;
>age : Symbol(Person.age, Decl(mappedTypeAsClauses.ts, 37, 26))
location?: string;
>location : Symbol(Person.location, Decl(mappedTypeAsClauses.ts, 38, 16))
}
type LazyPerson = Lazyify<Person>;
>LazyPerson : Symbol(LazyPerson, Decl(mappedTypeAsClauses.ts, 40, 1))
>Lazyify : Symbol(Lazyify, Decl(mappedTypeAsClauses.ts, 28, 34))
>Person : Symbol(Person, Decl(mappedTypeAsClauses.ts, 34, 2))
// Repro from #40833
type Example = {foo: string, bar: number};
>Example : Symbol(Example, Decl(mappedTypeAsClauses.ts, 42, 34))
>foo : Symbol(foo, Decl(mappedTypeAsClauses.ts, 46, 16))
>bar : Symbol(bar, Decl(mappedTypeAsClauses.ts, 46, 28))
type PickByValueType<T, U> = {
>PickByValueType : Symbol(PickByValueType, Decl(mappedTypeAsClauses.ts, 46, 42))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 48, 21))
>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 48, 23))
[K in keyof T as T[K] extends U ? K : never]: T[K]
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 49, 3))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 48, 21))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 48, 21))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 49, 3))
>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 48, 23))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 49, 3))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 48, 21))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 49, 3))
};
type T1 = PickByValueType<Example, string>;
>T1 : Symbol(T1, Decl(mappedTypeAsClauses.ts, 50, 2))
>PickByValueType : Symbol(PickByValueType, Decl(mappedTypeAsClauses.ts, 46, 42))
>Example : Symbol(Example, Decl(mappedTypeAsClauses.ts, 42, 34))
const e1: T1 = {
>e1 : Symbol(e1, Decl(mappedTypeAsClauses.ts, 53, 5))
>T1 : Symbol(T1, Decl(mappedTypeAsClauses.ts, 50, 2))
foo: "hello"
>foo : Symbol(foo, Decl(mappedTypeAsClauses.ts, 53, 16))
};
type T2 = keyof T1;
>T2 : Symbol(T2, Decl(mappedTypeAsClauses.ts, 55, 2))
>T1 : Symbol(T1, Decl(mappedTypeAsClauses.ts, 50, 2))
const e2: T2 = "foo";
>e2 : Symbol(e2, Decl(mappedTypeAsClauses.ts, 57, 5))
>T2 : Symbol(T2, Decl(mappedTypeAsClauses.ts, 55, 2))
// Repro from #41133
interface Car {
>Car : Symbol(Car, Decl(mappedTypeAsClauses.ts, 57, 21))
name: string;
>name : Symbol(Car.name, Decl(mappedTypeAsClauses.ts, 61, 15))
seats: number;
>seats : Symbol(Car.seats, Decl(mappedTypeAsClauses.ts, 62, 17))
engine: Engine;
>engine : Symbol(Car.engine, Decl(mappedTypeAsClauses.ts, 63, 18))
>Engine : Symbol(Engine, Decl(mappedTypeAsClauses.ts, 66, 1))
wheels: Wheel[];
>wheels : Symbol(Car.wheels, Decl(mappedTypeAsClauses.ts, 64, 19))
>Wheel : Symbol(Wheel, Decl(mappedTypeAsClauses.ts, 71, 1))
}
interface Engine {
>Engine : Symbol(Engine, Decl(mappedTypeAsClauses.ts, 66, 1))
manufacturer: string;
>manufacturer : Symbol(Engine.manufacturer, Decl(mappedTypeAsClauses.ts, 68, 18))
horsepower: number;
>horsepower : Symbol(Engine.horsepower, Decl(mappedTypeAsClauses.ts, 69, 25))
}
interface Wheel {
>Wheel : Symbol(Wheel, Decl(mappedTypeAsClauses.ts, 71, 1))
type: "summer" | "winter";
>type : Symbol(Wheel.type, Decl(mappedTypeAsClauses.ts, 73, 17))
radius: number;
>radius : Symbol(Wheel.radius, Decl(mappedTypeAsClauses.ts, 74, 30))
}
type Primitive = string | number | boolean;
>Primitive : Symbol(Primitive, Decl(mappedTypeAsClauses.ts, 76, 1))
type OnlyPrimitives<T> = { [K in keyof T as T[K] extends Primitive ? K : never]: T[K] };
>OnlyPrimitives : Symbol(OnlyPrimitives, Decl(mappedTypeAsClauses.ts, 78, 43))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 79, 20))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 79, 28))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 79, 20))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 79, 20))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 79, 28))
>Primitive : Symbol(Primitive, Decl(mappedTypeAsClauses.ts, 76, 1))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 79, 28))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 79, 20))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 79, 28))
let primitiveCar: OnlyPrimitives<Car>; // { name: string; seats: number; }
>primitiveCar : Symbol(primitiveCar, Decl(mappedTypeAsClauses.ts, 81, 3))
>OnlyPrimitives : Symbol(OnlyPrimitives, Decl(mappedTypeAsClauses.ts, 78, 43))
>Car : Symbol(Car, Decl(mappedTypeAsClauses.ts, 57, 21))
let keys: keyof OnlyPrimitives<Car>; // "name" | "seats"
>keys : Symbol(keys, Decl(mappedTypeAsClauses.ts, 82, 3))
>OnlyPrimitives : Symbol(OnlyPrimitives, Decl(mappedTypeAsClauses.ts, 78, 43))
>Car : Symbol(Car, Decl(mappedTypeAsClauses.ts, 57, 21))
type KeysOfPrimitives<T> = keyof OnlyPrimitives<T>;
>KeysOfPrimitives : Symbol(KeysOfPrimitives, Decl(mappedTypeAsClauses.ts, 82, 36))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 84, 22))
>OnlyPrimitives : Symbol(OnlyPrimitives, Decl(mappedTypeAsClauses.ts, 78, 43))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 84, 22))
let carKeys: KeysOfPrimitives<Car>; // "name" | "seats"
>carKeys : Symbol(carKeys, Decl(mappedTypeAsClauses.ts, 86, 3))
>KeysOfPrimitives : Symbol(KeysOfPrimitives, Decl(mappedTypeAsClauses.ts, 82, 36))
>Car : Symbol(Car, Decl(mappedTypeAsClauses.ts, 57, 21))
// Repro from #41453
type Equal<A, B> = (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? true : false;
>Equal : Symbol(Equal, Decl(mappedTypeAsClauses.ts, 86, 35))
>A : Symbol(A, Decl(mappedTypeAsClauses.ts, 90, 11))
>B : Symbol(B, Decl(mappedTypeAsClauses.ts, 90, 13))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 90, 21))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 90, 21))
>A : Symbol(A, Decl(mappedTypeAsClauses.ts, 90, 11))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 90, 60))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 90, 60))
>B : Symbol(B, Decl(mappedTypeAsClauses.ts, 90, 13))
type If<Cond extends boolean, Then, Else> = Cond extends true ? Then : Else;
>If : Symbol(If, Decl(mappedTypeAsClauses.ts, 90, 104))
>Cond : Symbol(Cond, Decl(mappedTypeAsClauses.ts, 92, 8))
>Then : Symbol(Then, Decl(mappedTypeAsClauses.ts, 92, 29))
>Else : Symbol(Else, Decl(mappedTypeAsClauses.ts, 92, 35))
>Cond : Symbol(Cond, Decl(mappedTypeAsClauses.ts, 92, 8))
>Then : Symbol(Then, Decl(mappedTypeAsClauses.ts, 92, 29))
>Else : Symbol(Else, Decl(mappedTypeAsClauses.ts, 92, 35))
type GetKey<S, V> = keyof { [TP in keyof S as Equal<S[TP], V> extends true ? TP : never]: any };
>GetKey : Symbol(GetKey, Decl(mappedTypeAsClauses.ts, 92, 76))
>S : Symbol(S, Decl(mappedTypeAsClauses.ts, 94, 12))
>V : Symbol(V, Decl(mappedTypeAsClauses.ts, 94, 14))
>TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 94, 29))
>S : Symbol(S, Decl(mappedTypeAsClauses.ts, 94, 12))
>Equal : Symbol(Equal, Decl(mappedTypeAsClauses.ts, 86, 35))
>S : Symbol(S, Decl(mappedTypeAsClauses.ts, 94, 12))
>TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 94, 29))
>V : Symbol(V, Decl(mappedTypeAsClauses.ts, 94, 14))
>TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 94, 29))
type GetKeyWithIf<S, V> = keyof { [TP in keyof S as If<Equal<S[TP], V>, TP, never>]: any };
>GetKeyWithIf : Symbol(GetKeyWithIf, Decl(mappedTypeAsClauses.ts, 94, 96))
>S : Symbol(S, Decl(mappedTypeAsClauses.ts, 96, 18))
>V : Symbol(V, Decl(mappedTypeAsClauses.ts, 96, 20))
>TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 96, 35))
>S : Symbol(S, Decl(mappedTypeAsClauses.ts, 96, 18))
>If : Symbol(If, Decl(mappedTypeAsClauses.ts, 90, 104))
>Equal : Symbol(Equal, Decl(mappedTypeAsClauses.ts, 86, 35))
>S : Symbol(S, Decl(mappedTypeAsClauses.ts, 96, 18))
>TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 96, 35))
>V : Symbol(V, Decl(mappedTypeAsClauses.ts, 96, 20))
>TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 96, 35))
type GetObjWithIf<S, V> = { [TP in keyof S as If<Equal<S[TP], V>, TP, never>]: any };
>GetObjWithIf : Symbol(GetObjWithIf, Decl(mappedTypeAsClauses.ts, 96, 91))
>S : Symbol(S, Decl(mappedTypeAsClauses.ts, 98, 18))
>V : Symbol(V, Decl(mappedTypeAsClauses.ts, 98, 20))
>TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 98, 29))
>S : Symbol(S, Decl(mappedTypeAsClauses.ts, 98, 18))
>If : Symbol(If, Decl(mappedTypeAsClauses.ts, 90, 104))
>Equal : Symbol(Equal, Decl(mappedTypeAsClauses.ts, 86, 35))
>S : Symbol(S, Decl(mappedTypeAsClauses.ts, 98, 18))
>TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 98, 29))
>V : Symbol(V, Decl(mappedTypeAsClauses.ts, 98, 20))
>TP : Symbol(TP, Decl(mappedTypeAsClauses.ts, 98, 29))
type Task = {
>Task : Symbol(Task, Decl(mappedTypeAsClauses.ts, 98, 85))
isDone: boolean;
>isDone : Symbol(isDone, Decl(mappedTypeAsClauses.ts, 100, 13))
};
type Schema = {
>Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 102, 2))
root: {
>root : Symbol(root, Decl(mappedTypeAsClauses.ts, 104, 15))
title: string;
>title : Symbol(title, Decl(mappedTypeAsClauses.ts, 105, 9))
task: Task;
>task : Symbol(task, Decl(mappedTypeAsClauses.ts, 106, 18))
>Task : Symbol(Task, Decl(mappedTypeAsClauses.ts, 98, 85))
}
Task: Task;
>Task : Symbol(Task, Decl(mappedTypeAsClauses.ts, 108, 3))
>Task : Symbol(Task, Decl(mappedTypeAsClauses.ts, 98, 85))
};
type Res1 = GetKey<Schema, Schema['root']['task']>; // "Task"
>Res1 : Symbol(Res1, Decl(mappedTypeAsClauses.ts, 110, 2))
>GetKey : Symbol(GetKey, Decl(mappedTypeAsClauses.ts, 92, 76))
>Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 102, 2))
>Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 102, 2))
type Res2 = GetKeyWithIf<Schema, Schema['root']['task']>; // "Task"
>Res2 : Symbol(Res2, Decl(mappedTypeAsClauses.ts, 112, 51))
>GetKeyWithIf : Symbol(GetKeyWithIf, Decl(mappedTypeAsClauses.ts, 94, 96))
>Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 102, 2))
>Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 102, 2))
type Res3 = keyof GetObjWithIf<Schema, Schema['root']['task']>; // "Task"
>Res3 : Symbol(Res3, Decl(mappedTypeAsClauses.ts, 113, 57))
>GetObjWithIf : Symbol(GetObjWithIf, Decl(mappedTypeAsClauses.ts, 96, 91))
>Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 102, 2))
>Schema : Symbol(Schema, Decl(mappedTypeAsClauses.ts, 102, 2))
// Repro from #44019
type KeysExtendedBy<T, U> = keyof { [K in keyof T as U extends T[K] ? K : never] : T[K] };
>KeysExtendedBy : Symbol(KeysExtendedBy, Decl(mappedTypeAsClauses.ts, 114, 63))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 118, 20))
>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 118, 22))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 118, 37))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 118, 20))
>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 118, 22))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 118, 20))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 118, 37))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 118, 37))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 118, 20))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 118, 37))
interface M {
>M : Symbol(M, Decl(mappedTypeAsClauses.ts, 118, 90))
a: boolean;
>a : Symbol(M.a, Decl(mappedTypeAsClauses.ts, 120, 13))
b: number;
>b : Symbol(M.b, Decl(mappedTypeAsClauses.ts, 121, 15))
}
function f(x: KeysExtendedBy<M, number>) {
>f : Symbol(f, Decl(mappedTypeAsClauses.ts, 123, 1))
>x : Symbol(x, Decl(mappedTypeAsClauses.ts, 125, 11))
>KeysExtendedBy : Symbol(KeysExtendedBy, Decl(mappedTypeAsClauses.ts, 114, 63))
>M : Symbol(M, Decl(mappedTypeAsClauses.ts, 118, 90))
return x;
>x : Symbol(x, Decl(mappedTypeAsClauses.ts, 125, 11))
}
f("a"); // Error, should allow only "b"
>f : Symbol(f, Decl(mappedTypeAsClauses.ts, 123, 1))
type NameMap = { 'a': 'x', 'b': 'y', 'c': 'z' };
>NameMap : Symbol(NameMap, Decl(mappedTypeAsClauses.ts, 129, 7))
>'a' : Symbol('a', Decl(mappedTypeAsClauses.ts, 131, 16))
>'b' : Symbol('b', Decl(mappedTypeAsClauses.ts, 131, 26))
>'c' : Symbol('c', Decl(mappedTypeAsClauses.ts, 131, 36))
// Distributive, will be simplified
type TS0<T> = keyof { [P in keyof T as keyof Record<P, number>]: string };
>TS0 : Symbol(TS0, Decl(mappedTypeAsClauses.ts, 131, 48))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 135, 9))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 135, 23))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 135, 9))
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 135, 23))
type TS1<T> = keyof { [P in keyof T as Extract<P, 'a' | 'b' | 'c'>]: string };
>TS1 : Symbol(TS1, Decl(mappedTypeAsClauses.ts, 135, 74))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 136, 9))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 136, 23))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 136, 9))
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 136, 23))
type TS2<T> = keyof { [P in keyof T as P & ('a' | 'b' | 'c')]: string };
>TS2 : Symbol(TS2, Decl(mappedTypeAsClauses.ts, 136, 78))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 137, 9))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 137, 23))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 137, 9))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 137, 23))
type TS3<T> = keyof { [P in keyof T as Exclude<P, 'a' | 'b' | 'c'>]: string };
>TS3 : Symbol(TS3, Decl(mappedTypeAsClauses.ts, 137, 72))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 138, 9))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 138, 23))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 138, 9))
>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 138, 23))
type TS4<T> = keyof { [P in keyof T as NameMap[P & keyof NameMap]]: string };
>TS4 : Symbol(TS4, Decl(mappedTypeAsClauses.ts, 138, 78))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 139, 9))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 139, 23))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 139, 9))
>NameMap : Symbol(NameMap, Decl(mappedTypeAsClauses.ts, 129, 7))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 139, 23))
>NameMap : Symbol(NameMap, Decl(mappedTypeAsClauses.ts, 129, 7))
type TS5<T> = keyof { [P in keyof T & keyof NameMap as NameMap[P]]: string };
>TS5 : Symbol(TS5, Decl(mappedTypeAsClauses.ts, 139, 77))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 140, 9))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 140, 23))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 140, 9))
>NameMap : Symbol(NameMap, Decl(mappedTypeAsClauses.ts, 129, 7))
>NameMap : Symbol(NameMap, Decl(mappedTypeAsClauses.ts, 129, 7))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 140, 23))
type TS6<T, U, V> = keyof { [ K in keyof T as V & (K extends U ? K : never)]: string };
>TS6 : Symbol(TS6, Decl(mappedTypeAsClauses.ts, 140, 77))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 141, 9))
>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 141, 11))
>V : Symbol(V, Decl(mappedTypeAsClauses.ts, 141, 14))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 141, 29))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 141, 9))
>V : Symbol(V, Decl(mappedTypeAsClauses.ts, 141, 14))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 141, 29))
>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 141, 11))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 141, 29))
// Non-distributive, won't be simplified
type TN0<T> = keyof { [P in keyof T as T[P] extends number ? P : never]: string };
>TN0 : Symbol(TN0, Decl(mappedTypeAsClauses.ts, 141, 87))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 145, 9))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 145, 23))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 145, 9))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 145, 9))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 145, 23))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 145, 23))
type TN1<T> = keyof { [P in keyof T as number extends T[P] ? P : never]: string };
>TN1 : Symbol(TN1, Decl(mappedTypeAsClauses.ts, 145, 82))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 146, 9))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 146, 23))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 146, 9))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 146, 9))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 146, 23))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 146, 23))
type TN2<T> = keyof { [P in keyof T as 'a' extends P ? 'x' : 'y']: string };
>TN2 : Symbol(TN2, Decl(mappedTypeAsClauses.ts, 146, 82))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 147, 9))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 147, 23))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 147, 9))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 147, 23))
type TN3<T> = keyof { [P in keyof T as Exclude<Exclude<Exclude<P, 'c'>, 'b'>, 'a'>]: string };
>TN3 : Symbol(TN3, Decl(mappedTypeAsClauses.ts, 147, 76))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 148, 9))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 148, 23))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 148, 9))
>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --))
>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --))
>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 148, 23))
type TN4<T, U> = keyof { [K in keyof T as (K extends U ? T[K] : never) extends T[K] ? K : never]: string };
>TN4 : Symbol(TN4, Decl(mappedTypeAsClauses.ts, 148, 94))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 149, 9))
>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 149, 11))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 149, 26))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 149, 9))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 149, 26))
>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 149, 11))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 149, 9))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 149, 26))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 149, 9))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 149, 26))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 149, 26))
type TN5<T, U> = keyof { [K in keyof T as keyof { [P in K as T[P] extends U ? K : never]: true }]: string };
>TN5 : Symbol(TN5, Decl(mappedTypeAsClauses.ts, 149, 107))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 150, 9))
>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 150, 11))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 150, 26))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 150, 9))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 150, 51))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 150, 26))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 150, 9))
>P : Symbol(P, Decl(mappedTypeAsClauses.ts, 150, 51))
>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 150, 11))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 150, 26))