ikuma-t.

検索

type-challenges 5日目: 43-Exclude

に公開

問題 & 解答

組み込みのExclude<T, U>を自前で実装する

Conditional Typesの分配法則を用いて、次のように記述する。

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

例えば

  • T"a" | "b" | "c" | "d"
  • U"c" | "d" | "e" | "f"

であるとき、まず"a"Uのサブセットではないので、Tつまり"a"が返る。 一つ飛ばして"c"Uのサブセットなので、neverが返る。

分配法則によりこれらの結果を結合したものが返るのでMyExclude<"a" | "b" | "c" | "d", "c" | "d" | "e" | "f">"a" | "b"をあらわす

調べたこと

Exclude型

差集合を表す型

// Exclude<UnionType, ExcludedMembers>
// (a, b, c)
type T0 = Exclude<"a" | "b" | "c", "a">
// type T0 = "b" | "c"
type T1 = Exclude<"a" | "b" | "c" | "d", "c" | "d" | "e" | "f">
// type T1 = "a" | "b"

TypeScript: Documentation - Utility Types🔗

Conditional TypesとDistributive(分配法則)

  • Conditional types がGeneric型である時、Union型が渡された場合は、分配法則に従う。
// 各Tがanyでを満たせば`T[]`を返す
type ToArray<T> = T extends any ? T[] : never;
type StrArrOrNumArr = ToArray<string | number>;

StrArrOrNumArrでは、TとしてUnion型のstring | numberが与えられている。

// StrArrOrNumArrの右辺は次のようになる(ちょっと表現としては変だけど)
(string | number) extends any ? T[] : never
// 分配法則により次のように読み下せる
(string extends any ? string[] : never) | (number extends any ? number[] : never)
// anyはすべてを満たすので`StrArrOrNumArr`はこうなる
string[] | number[]
ikuma-t

ikuma-t

ABOUT

9割笑顔、1割 (´・ω・) なエンジニア