0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Homomorphic Mapped Types とは

Homomorphic Mapped Types は、Mapped Types の一種で、オプショナル修飾子?readonlyなどの修飾子をそのままに、オブジェクトの型の構造を保持したまま新しい型を宣言できることが特徴的です。
書き方にMapped Types との違いは特になく、{[P in X]: Y}のように記述しますが、これがHomomorphic Mapped Types となる条件は、Xの部分がオブジェクトのプロパティキーの型となっていることです。
つまり、Homomorphic Mapped Types は、{[P in keyof T]: U}の形で表されるものとなります。

Tの部分にオブジェクトのキー(のユニオン型)が渡されると、宣言されるオブジェクトの型にはTと同じプロパティキーが含まれることになります(プロパティの型自体はUの部分によって変化します)。

Homomorphic Mapped Types の性質

?readonlyの保持

以下の例では、Mapped Types {[P in X]: Y}in Xの部分にkeyofを使ってオブジェクトのキーを指定した場合には?readonlyが保持され、オブジェクトのキーを単にユニオン型で指定した場合には修飾子が保持されないことを確認できます。

type Obj = {
  readonly num: number
  str?: string
}

type Homomorphic = {
  [P in keyof Obj]: Obj[P]
}
// type Homomorphic = {
//     readonly num: number;
//     str?: string | undefined;
// }

type keyStr = "num" | "str"

type NonHomomorphic = {
  [P in keyStr]: Obj[P]
}
// type NonHomomorphic = {
//     num: number;
//     str: string | undefined;
// }

Union Distribution

Homomorphic Mapped Types には、Conditional Types と同様にユニオン型を分配する働き(Union Distribution)があります。

型引数TをとるHomomorphic Mapped Types HMT<T>に対してユニオン型X | Yを渡すと、HMT<X | Y>HMT<X> | HMT<Y>のようにユニオン型が分配される形となります。

型引数TをとるHomomorphic Mapped Types HMT<T>と通常のMapped Types MT<T>のそれぞれにユニオン型を渡してみます。

type Obj = {
    readonly num: number
    str?: string
  }
  
type Obj2 = {
    foo: string
    bar: number
}

type MT<X extends PropertyKey> = {
[P in X]: string
}

// type UnionMT = {
//     num: string;
//     str: string;
//     foo: string;
//     bar: string;
// }
type UnionMT = MT<keyof Obj | keyof Obj2>

type HMT<T> = {
    [P in keyof T]: string
}

//type UnionHMT = HMT<Obj> | HMT<Obj2>
type UnionHMT = HMT<Obj | Obj2>

Mapped Types MT<X extends PropertyKey>keyof Objkeyof Obj2のユニオン型を渡した場合にはUnion Distribution は働かずに、2つのオブジェクトのプロパティキーを合併したオブジェクト型になっています。

一方でHomomorphic Mapped Types HMT<T>ObjObj2のユニオン型を渡した場合にはUnion Distribution が働き、HMT<Obj> | HMT<Obj2>とユニオン型が分配されていることがわかります。

Homomorphic Mapped Types と準同型写像

構造を保存する写像である、準同型写像(homomorphic mapping)が名前の由来となっているようです。
Homomorphic Mapped Types{[P in keyof T]: U}は、作成元となるオブジェクト型Tと全く同じプロパティキーをもつため、オブジェクトの構造が保存されていることをhomomorphicと表しているようですね。

A mapped type of the form { [P in keyof T]: X } is homomorphic with T (because it has the same set of properties as T) and now preserves the optional and readonly modifiers as they exist on the properties in T.

ちなみに、ユニオン型を分配する働きが追加されたころは、Isomorphic Mapped Types と呼ばれていたようです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?