type-challenges
13 - hello-world
type HelloWorld = string // expected to be a string
4 - Pick
type MyPick<T extends {}, K extends keyof T> = {[P in K]: T[P] };
memo
in
を正しく扱えるかが大切
P in K
の場合K
がUnion型である場合そのUnion型に対して反復処理を行う。
K = 'foo' | 'bar'
の場合{[P in K]: string}
なら
{
foo: string,
bar: string
}
という型になる。
7 - Readonly
type MyReadonly<T extends {}> = {readonly [P in keyof T]: T[P]}
T
がオブジェクトの場合、keyof T
でkey
のUnion型が作れる。
11 - Tuple to Object
type TupleToObject<T extends readonly (string|number|symbol)[]> = {
[P in T[number]]: P
};
memo
配列型に対してインデックスにnumber
を指定するとUnion型にできる。
const currencies = ["CNY", "EUR", "GBP", "JPY", "KRW", "USD"] as const;
type Currency = typeof currencies[number];
// => "CNY" | "EUR" | "GBP" | "JPY" | "KRW" | "USD"
一度Unionにしたら以前のオブジェクト型の作成のように[P in T]: P
で各プロパティを定義していく。
9 - Deep Readonly
type DeepReadonly<T> = {
readonly [P in keyof T]:
T[P] extends () => any ? T[P] :
T[P] extends {[key: string|number|symbol]: any} ? DeepReadonly<T[P]> :
T[P];
}
14 - First of Array
type First<T extends any[]> = T extends [] ? never : T[0];
memo
条件分岐は<Type> extends ? A : B
で行う。
18 - Length of Tuple
type Length<T extends readonly any[]> = T["length"];
Genericsの制限はextends <Type>
で行う。
制限を設けた場合それを満たさない引数は渡せなくなるし、上記の場合Tがany[]
型として推論されるのでT["length"]
で取得ができるようになる。
43 - Exclude
type MyExclude<T, U> = T extends U ? never : T;
T extends U
がUnion型同士の場合
T extends U ? <重複している値> : <重複していない値>
になるみたい。
189 - Awaited
一応これで通るけど問題が間違っている気がする。
type PromiseLike = { then: (onfulfilled: (arg: any) => any) => any }
type MyAwaited<T extends PromiseLike> =
T extends Promise<infer U> ?
U extends Promise<any> ?
MyAwaited<U>:
U:
T extends { then: (onfulfilled: (arg: infer V) => any) => any } ?
V:
never;
Promiseなのに.catch
がないものを受け入れるようになっている?
type MyAwaited<T extends Promise<any>> =
T extends Promise<infer U> ?
U extends Promise<any> ?
MyAwaited<U>:
U:
never;
268 - If
type If<C extends boolean, T, F> = C extends true ? T : F;
extends
で条件分岐させるだけ。
533 - Concat
type Concat<T extends any[], U extends any[]> = [...T, ...U];
配列型にはスプレッド構文が使える。
898 - Includes
3057 - Push
type Push<T extends any[], U> = [...T, U]
3060 - Unshift
type Unshift<T extends any[], U> = [U, ...T];
3312 - Parameters
type MyParameters<T extends (...args: any[]) => any> =
T extends (...args: infer U) => any ?
U : never
3 - Omit
type MyOmit<T, K extends keyof T> = {
[P in Exclude<keyof T, K>]: T[P]
}
8 - Readonly 2
type MyReadonly2<T, K extends keyof T = keyof T> = {
readonly [P in K]: T[P]
} & Omit<T,K>;
10 - Tuple to Union
type TupleToUnion<T extends readonly any[]> = T[number];