[P in K]: T[P] } K extends keyof T で、第二引数が第一引数のキーのみを受け取るよう制約を設ける。 [P in K] (Mapped Types)で、第二引数のユニオン型(K)を順に取り出す。 T[P] (Indexed Access Types)で、キーに対応するTの型を取り出す。
c: string } type Bar = MyPick<Foo, "a" | "c"> // Bar = { a: number; c: string } type MyPick<T, K extends keyof T> = { [P in K]: T[P] } "a" | "c" extends keyof Foo ↓ "a" | "c" extends "a" | "b" | "c"
{ [P in K]: T[P] } K extends keyof T で、第二引数が第一引数のキーのみを受け取るよう制約を設ける。 [P in K] (Mapped Types)で、第二引数のユニオン型(K)を順に取り出す。 T[P] (Indexed Access Types)で、キーに対応するTの型を取り出す。
U : T type ExampleType = Promise<string> type Result = MyAwaited<ExampleType> // string 👉 U には推論された任意の型が入る 👉 infer で推論した型は Conditional Types 内で利用できる 👉 ただ、この場合だとPromiseがネストしている場合に対応できない。。 type Result = MyAwaited<Promise<Promise<string>>> // Promise<string> 💡 解答例
Promise<infer U> ? U : T 👉 オブジェクト型の特定のプロパティの型を取り出す type Value<T, K extends keyof T> = T extends Record<K, infer U> ? U : never type Man = { name: string; age: number; } type Name = Value<Man, 'name'>; // string type Age = Value<Man, 'age'>; // number ✨ Inferring Within Conditional Types はこういうときに使える