Closed28

TypeScript型パズルpalette

tomixytomixy

絵描きが絵の具を選ぶような感覚で型を組み合わせられるようになれたらにゃ…

目次

そのうちつくるにゃ

出典

今のところは下記問題集の自分なりの解答ノートにすぎないにゃ
一つの問題の解答をなるべく粒度の小さい型に分割するようにしているにゃ
https://github.com/type-challenges/type-challenges/

tomixytomixy

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]
}
tomixytomixy

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]>
}
tomixytomixy

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]
tomixytomixy

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
tomixytomixy

Length - タプルの要素数を取得(Tuple -> number)

type Length<T extends readonly any[]> = T['length']
tomixytomixy

Exclude - 除外(Object -> Object)

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

Awaited - Promiseを剥がす(Promise<T> -> T)

type MyAwaited<T> = T extends Promise<infer R> ? MyAwaited<R> : T
tomixytomixy

If - truthyなら前の値を返す(any, any, any -> any)

type If<C extends boolean, T, F> = C extends true ? T : F
tomixytomixy

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]
tomixytomixy

IsEqual - 等しいか判定(any, any -> boolean)

type IsEqual<T, U> 
  = (<G>() => G extends T ? 1 : 2) extends <G>() 
    => G extends 
        U ? 1 : 2 
          ? true : false
tomixytomixy

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
tomixytomixy

Parameters - 関数の引数群をタプルで返す(Function -> Tuple)

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

ReturnType - 関数の戻り値を取得(Function -> any)

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

Unbox - Object or ArrayならUを返す(any -> any)

type Unbox<T> = T extends {
  [k: string]: infer U
} ? U : T extends (infer U)[]
  ? U : T
tomixytomixy

isPrimitive - プリミティブならTを返す(any -> any)

type isPrimitive<T> = T extends Unbox<T> ? T : never
tomixytomixy

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
}
tomixytomixy

Pop - 配列の最後の要素を除く(Array -> Array)

type Pop<T extends any[]> 
  = T extends [...infer Items, infer _]
    ? Items
    : undefined
tomixytomixy

PromiseAll - 型定義バージョン

declare function PromiseAll<T extends any[]>(
  values: readonly [...T]
): Promise<{ [k in keyof T]: T[k] extends Promise<infer R> ? R : T[k] }>
tomixytomixy

LookUp - Union型から特定の型を属性値で検索(Union -> any)

type LookUp<U, T> = U extends { type: T } ? U : never
tomixytomixy

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
tomixytomixy

Capitalize - 頭文字を大文字に変換

type MyCapitalize<S extends string> 
  = S extends `${infer First}${infer Rest}`
    ? `${Uppercase<First>}${Rest}`
    : S
tomixytomixy

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
tomixytomixy

AppendArgument - 引数を追加した関数を生成

type AppendArgument<Fn, A> 
  = Fn extends (...args: infer P) 
    => infer R
      ? (...args: [...P, A]) => R
      : never
tomixytomixy

Permutation - タプルの中の数の順列を生成

type Permutation<T, U = T> 
  = [T] extends [never]
    ? []
    : T extends U
      ? [T, ...Permutation<Exclude<U, T>>]
      : []
tomixytomixy

StringToTuple - 文字列を各文字のタプル化

type StringToTuple<S extends string> 
  = S extends `${infer First}${infer Rest}`
    ? [First, ...StringToTuple<Rest>]
    : []
tomixytomixy

LengthOfString - 文字列の長さを取得

type LengthOfString<S extends string> = StringToTuple<S>['length']
tomixytomixy

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にクローズされました