Closed28
TypeScript型パズルpalette
絵描きが絵の具を選ぶような感覚で型を組み合わせられるようになれたらにゃ…
目次
そのうちつくるにゃ
出典
今のところは下記問題集の自分なりの解答ノートにすぎないにゃ
一つの問題の解答をなるべく粒度の小さい型に分割するようにしているにゃ
Pick - 抽出する(Object -> Object)
type MyPick<T, K extends keyof T> = {
[U in K]: T[U]
}
Omit - プロパティ削除(Object -> Object)
type MyOmit<T, K extends keyof T> = {
[P in Exclude<keyof T, K>]: T[P]
}
Readonly - 読み取り専用にする(Object -> Object)
全て読み取り専用にする
type MyReadonly<T> = {
readonly [K in keyof T]: T[K]
}
読み取り専用範囲を指定(Kが未設定なら全て読み取り専用にする)
type MyReadonly2<T, K extends keyof T = keyof T> = {
readonly [k in K]: T[k]
} & Omit<T, K>
再帰的実行でネスト対応
type DeepReadonly<T> = {
readonly [P in keyof T]: T[P] extends isPrimitive<T[P]>
? T[P]
: DeepReadonly<T[P]>
}
TupleToObject - 各値をキーと値にマッピング(Tuple -> Object)
type TupleToObject<T extends readonly [...T]> = {
[K in T[number]]: K
}
TupleToUnion - タプルの各値をUnionに展開(Tuple -> Union)
type TupleToUnion<T extends unknown[]> = T[number]
First - 配列の最初の要素を抽出(Array<T> -> T)
type First<T extends any[]> =
T extends [infer First, ...infer _]
? First
: never
Last - 配列の最後の要素型を取得(Array<any> -> any)
type Last<T extends any[]> = T extends [...any, infer L] ? L : never
Length - タプルの要素数を取得(Tuple -> number)
type Length<T extends readonly any[]> = T['length']
Exclude - 除外(Object -> Object)
type MyExclude<T, U extends T> = T extends U ? never : T
Awaited - Promiseを剥がす(Promise<T> -> T)
type MyAwaited<T> = T extends Promise<infer R> ? MyAwaited<R> : T
If - truthyなら前の値を返す(any, any, any -> any)
type If<C extends boolean, T, F> = C extends true ? T : F
Concat - 配列合体(Array -> Array)
type Concat<T extends Array<any>, U extends Array<any>> = [...T, ...U]
Push - 配列の最後に付け加える(Array, any -> Array)
type Push<T extends Array<any>, U> = [...T, U]
Unshift - 配列の最初に追加する(Array, any -> Array)
type Unshift<T extends Array<any>, U> = [U, ...T]
IsEqual - 等しいか判定(any, any -> boolean)
type IsEqual<T, U>
= (<G>() => G extends T ? 1 : 2) extends <G>()
=> G extends
U ? 1 : 2
? true : false
Includes - 配列に含まれるか判定(Array, any -> boolean)
type Includes<T extends readonly any[], U>
= T extends [T[0], ...infer Rest]
? IsEqual<T[0], U> extends true
? true : Includes<Rest, U> : false
Parameters - 関数の引数群をタプルで返す(Function -> Tuple)
type MyParameters<T extends (...args: any[]) => any>
= T extends (...args: infer U)
=> any ? U : never
ReturnType - 関数の戻り値を取得(Function -> any)
type MyReturnType<T> = T extends (...args: any[]) => infer U ? U : never
Unbox - Object or ArrayならUを返す(any -> any)
type Unbox<T> = T extends {
[k: string]: infer U
} ? U : T extends (infer U)[]
? U : T
isPrimitive - プリミティブならTを返す(any -> any)
type isPrimitive<T> = T extends Unbox<T> ? T : never
ChainOptions - メソッドチェーンの型付け
type Chainable<Options extends object = {}> = {
option<K extends string, V>(
key: K extends keyof Options ? never : K,
value: V
): Chainable<Options & { [_ in K]: V }>
get(): Options
}
Pop - 配列の最後の要素を除く(Array -> Array)
type Pop<T extends any[]>
= T extends [...infer Items, infer _]
? Items
: undefined
PromiseAll - 型定義バージョン
declare function PromiseAll<T extends any[]>(
values: readonly [...T]
): Promise<{ [k in keyof T]: T[k] extends Promise<infer R> ? R : T[k] }>
LookUp - Union型から特定の型を属性値で検索(Union -> any)
type LookUp<U, T> = U extends { type: T } ? U : never
TrimLeft - 先頭の空白を削除
type TrimLeft<S extends string>
= S extends `${Empty}${infer A}`
? TrimLeft<A>
: S
TrimRight - 末尾の空白を削除
type EscapeChar = ' ' | '\n' | '\t'
type TrimRight<S extends string>
= S extends `${infer Rest}${EscapeChar}`
? TrimRight<Rest>
: S
Trim - 両端の空白を削除
type EscapeChar = ' ' | '\n' | '\t'
type Trim<S extends string> = S extends
| `${EscapeChar}${infer Rest}`
| `${infer Rest}${EscapeChar}`
? Trim<Rest>
: S
Capitalize - 頭文字を大文字に変換
type MyCapitalize<S extends string>
= S extends `${infer First}${infer Rest}`
? `${Uppercase<First>}${Rest}`
: S
Replace - 一箇所置換
type Replace<S extends string, From extends string, To extends string>
= From extends ''
? S
: S extends `${infer Head}${From}${infer Tail}`
? `${Head}${To}${Tail}`
: S
ReplaceAll - 全て置換
type ReplaceAll<S extends string, From extends string, To extends string>
= From extends ''
? S
: S extends `${infer Head}${From}${infer Tail}`
? `${Head}${To}${ReplaceAll<Tail, From, To>}`
: S
AppendArgument - 引数を追加した関数を生成
type AppendArgument<Fn, A>
= Fn extends (...args: infer P)
=> infer R
? (...args: [...P, A]) => R
: never
Permutation - タプルの中の数の順列を生成
type Permutation<T, U = T>
= [T] extends [never]
? []
: T extends U
? [T, ...Permutation<Exclude<U, T>>]
: []
StringToTuple - 文字列を各文字のタプル化
type StringToTuple<S extends string>
= S extends `${infer First}${infer Rest}`
? [First, ...StringToTuple<Rest>]
: []
LengthOfString - 文字列の長さを取得
type LengthOfString<S extends string> = StringToTuple<S>['length']
Flatten - ネスト配列をフラット化
type Flatten<T extends any[], R extends any[] = []> = T extends [
infer L,
...infer Rest
]
? L extends any[]
? Flatten<Rest, [...R, ...Flatten<L>]>
: Flatten<Rest, [...R, L]>
: R
このスクラップは2022/07/13にクローズされました