Open29

type-challenges

ken7253ken7253

4 - Pick

type MyPick<T extends {}, K extends keyof T> = {[P in K]: T[P] };
ken7253ken7253

memo

inを正しく扱えるかが大切
P in Kの場合KがUnion型である場合そのUnion型に対して反復処理を行う。

K = 'foo' | 'bar'の場合{[P in K]: string}なら

{
  foo: string,
  bar: string
}

という型になる。

ken7253ken7253

11 - Tuple to Object

type TupleToObject<T extends readonly (string|number|symbol)[]> = {
  [P in T[number]]: P
};
ken7253ken7253

https://www.typescriptlang.org/play?#code/PQKgUABBCM0QtBAKgVwA4BsCmEAuB7CAeQCMArLAY10gXnodpIE8IBnASwDt98uIAFAAFOPPgEoIAYkC4SoCxfafnJVc8ANZZmbWrSl6IgK5jA8qo6ogfoZA6wyBrhkBJDIHXlQIoMgNeVAUQyBABkC6DIDsGQCAqgEgUvDWZgADcAQwwULBtAQGNAEwZAKoZANYZADoZAcoZAeoZACYYvQGj1QGsGQEhNQG3jQE0GQGiGXJtAfO1AUYjAdQZAPwZSwCAGUwhAaPlACQZABwZALH-2gANh3G0oSj42XDx0bAgAXggAbQByXCw2DDCVgBoIFYBbfAATLAwIAGZd-aPT84ANa8OTs4gATRWAXQgwtggJrhTdq4ZhoHAAJw2KAw00WqEwWCQ+FIFGoAB4QWD8AAzGYIgB8EGAwAgWAAHmDqFhjhAAN54DZbABc+3Wm22e2ed0uKxZXNeV05t1ejz5woeT3F715Nxe5w+AF9aMNBu1CQBxDi4AASKBIgHMGQBdHoBYqIqfQAFrhcGg2EziaNKOaAHRkNhO-DggDmwFgwDIYTAIGAYBDoAgAH1I1Ho1GIIBlBjj+UAzQyAH4ZAJMMNkAGFGAU0UIzH8+GIEGQ5icPDsEiUSo0UhSWT1lxjn9IWFjnwMKwBFNwdxPQAfLgoA4kLDgvtsZjD-AYcRLT6Exa02hLAAKEG4yCWg+Ho8+nxZK7ACoA3CGwGGC-mIIAxhkAnQxZQCNDCnb3nL7HixwDmgPdNS3SIAAogAjigER7ABFIqBACoQNi4L4Ac+xCKW8COhE2BcJ6GzACguAcBgbArCGAJTHicyLKsbJbJKco8kKtGPPR3IfN8vz-JMNAkb+sxYAAckOI7ggsyzQHsABMewXHsAAsrF-FxYBcWRWAALIcGSwlLKJ+xidcUn7NJXw-PJHElqCOAAILCeWiLIso6Kljiyn4qeYB-pQvwbJptAQZSuBosBoEYDWPGVvZ-mObiuA8fiez0lRYR8glKzHrK3JXGKtFXKl-ISpl3KPDlUofPlrwfNB+KxT5kHooFEQhQiYWohF5lOdFCL8Tu4Kxf+0AstAqViSyYmpRcLIXKl0kstJFVVVAvnVnVwU2U11aRcpalkj19J9TAOW6XyumjeNOWGXyhmzTsYCfKGJLIWw8Dkn5j3gvB4JueZpKvR61mhXZzVoksWniZ8cUKvOZ7niAr5voWgCE1l4t7XoAwwwWDDb5FsGoC0ISgDHkYAKt42IAjoqAJDmZqWtatr2mwjoum6Hrer6YSAgA7qOfoBlAeOE4A0ZHlBaVo2nawAOs6rrul6PrQMAbDTrhHCTDjEDeIAa3JeIATVGADIZAuU8Lot0xL3r+oGwZgEAA

memo

https://typescriptbook.jp/tips/generates-type-from-array#すべてのリテラル型が欲しい

配列型に対してインデックスに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で各プロパティを定義していく。

ken7253ken7253

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];
}
ken7253ken7253

memo

複雑な条件式を組む場合、switchのようなものは用意されていないが
extends <Type> ? A : Bでいけるので、それをつなげて擬似的にswitchのように書ける。
分かりづらいのでインデントを揃えたほうがいい。

型定義は再帰的に利用する。

ken7253ken7253

https://www.typescriptlang.org/ja/play?ssl=2&ssc=20&pln=2&pc=3#code/PQKgUABBCcELQQCIFNkAcICVkEMAmA9gHYA2AnpPHNTZQEZkQCCRALgBbGMBiArhAAoAAjjYAzXgEoIAYkC0coCxfWQCdchUoxkE6AK2QBjVnADWyMgGdZeVGkqUZDiICuYwPKqdqICqGQGsMgDoZA5QyA9QyAEwyAdgyAmgyAngyAZgwhgIsMgJcMgIcMgD8MgP0MyYAQ-4BSDIARDIDODIC6DCGArQxe3v7BgEkMgLGKgAx6gCFugNYMgJD-lYC1UYD+DIBryoBRDIBAOoAUro1hgNEMAAYo6Nj4xOQAPAAqAHxjlYD52oCjEYDqDIB+DGGAQAzuEIDKDCGATVGAMhmA5gyA9gzlgaEdlYCORoDGDFGAIgwjgBYMgM8GgFnaWyigHkGQAGDIBVBg++0AsomAdCVAIAMgCLUwAOpvCAvFAJ0MgCsGQCWDDdAMABgDtDUaAUf1AIGRN0AQgw9HaAbQZAMkM+y2gGkGLbwwD3yoBfgKxgAU0nqADctAKAMWMAjQzJDGVQDVDIAFhmSo2O3yu8MAV4GAMCVlYBquMagERjQBkRvLvoAZBiugFkGPaHKCUQDR8oAJBkADgxHMZO1jmSisMhoZAQAAaEAAvBAAN4QShQAAeAC4gyGoLGIDgowBGUOxuhRgDk7AAlumUwBfFNkDPsMy5qAFy1Qd2eiAAUTDnsMyDw-ujKdUMw0EEjbbjUA76nI8aTKf7almjDTEEzOfz7fHXaL05LZHTMYgFfX1a9CwIhFbkzQ00HZDm3qWEGAwAg5k4vBILboXvMOAAtl6cJYxvXG6xm2NKCdADKwgC8AHEs1YAAJXg6CuQAuj0AWKjRkALH-2FYVg0HMCMrxdfR2AAOh0cwCIIZQAHNgGgYAdBwMAQGAMAmNACAAH12I4ziOJOY5GkAZoZkkASYZKkADCjAFNFNiuKk1iIAYpjtyQGxjwnRYLwDQNKAHCcIAAbQABQgLMiAgUwyAIMQIAWABdCMUwWfSrIgZAwz-Ig8EsARpD9C9REYAB+SyHIgWy43svTHOc1z3KDHTTKjcxWGUIzyIAHyIXhXyfZQUvMMhMoIEgbPjIgyDzCAAsPZSNEWByLxC2MwqsgBuMAC2YkBJOkziIEAMYYMSCMUMU6rr2Nkxis1fNAyNYCAFODWsAEdeBwEgABo6wbAwZrKsRlAIV9pyEbc4HwlaSGQIhyOQcxgF4VgsxIcxczABSmAPJSF3mc8Wpej0vX0T9rtbHTKB-La5kW5aSDmSrPtPc91rBps8CWJZVrAKz5L+n1Ww0qAE0ELyLwAJmJ+h4sS5LKH0KM8djPAozoAgCtwIgU2QWnRwgcjOb7WN2F5vnYyzKNEt4ZAubjHQMwSpLLrLIXNz54xi2QEgSAIBW4yV2MSCjEGheXHN0cNunDdffXM1LTHDbzE2+xt2NNwLNqFKRv8W3UzS4eHQn-RJsmx07Icp1lqmg5PCAaaDedg8YBmICZlnRFjyOOZjvmtK7HmM6FrOhwF3PDfzxgRdm5Rxcl2MS4gaXpzD+Wq51uMa5V5c1Y1rWna5mu9YgGuDaFmd03tvmzbzn2Lf7n2dKt1dHb5u2uYXjdKBdpj2uGkaIEAQmsQgxHrAGGGQB1hi3rqxrAUBKAvQBjyMAFW9KkAR0VAEhzVD0Mw7DcPMfCiJIsjKOoqIcwAB3ZAygaJ0SgLfB+gBoyJGGhDCWEcLADwoRYipEKJUWAOYAqd0szEFdFAiARRABrcucC4CCP7INQb-DBlFaL0UYmAIAA

ken7253ken7253

18 - Length of Tuple

type Length<T extends readonly any[]> = T["length"];
ken7253ken7253

Genericsの制限はextends <Type>で行う。
制限を設けた場合それを満たさない引数は渡せなくなるし、上記の場合Tがany[]型として推論されるのでT["length"]で取得ができるようになる。

ken7253ken7253

43 - Exclude

type MyExclude<T, U> = T extends U ? never : T;
ken7253ken7253

T extends UがUnion型同士の場合
T extends U ? <重複している値> : <重複していない値>になるみたい。

ken7253ken7253

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;
ken7253ken7253

533 - Concat

type Concat<T extends any[], U extends any[]> = [...T, ...U];
ken7253ken7253

3312 - Parameters

type MyParameters<T extends (...args: any[]) => any> = 
  T extends (...args: infer U) => any ?
    U : never
ken7253ken7253

3 - Omit

type MyOmit<T, K extends keyof T> = {
  [P in Exclude<keyof T, K>]: T[P]
}
ken7253ken7253

8 - Readonly 2

type MyReadonly2<T, K extends keyof T = keyof T> = {
  readonly [P in K]: T[P]
} & Omit<T,K>;
ken7253ken7253

10 - Tuple to Union

type TupleToUnion<T extends readonly any[]> = T[number];