Type ScriptのOmitヘルプタイプ[中訳]

6708 ワード

作者:Marius Schoolz
リンク:https://mariusschulz.com/blog/the-omit-helper-type-in-typescript
3.5バージョンの後、Type Scriptはlib.s 5.5 d.tsにOmitヘルプタイプを追加しました.​Omitタイプは、他のオブジェクトタイプから属性を削除し、新しいオブジェクトタイプを作成することができます.type User = {id: string;name: string;email: string;};type UserWithoutEmail = Omit;// :type UserWithoutEmail = {id: string;name: string;};lib.s 5.d.ts内の​Omitヘルプタイプの長さは、このようにする._/**__* Construct a_ _type_ _with the properties of T except_ _for_ _those in_ _type_ _K.__ */_type Omit = Pick>;このタイプの定義を明確に説明し、その原理を理解して、自分のバージョンを実現して、その機能を復元してみます.
Omitヘルプのタイプを定義します.
私たちは先に上のUserタイプから始めます.type User = {id: string;name: string;email: string;};まず、すべてのUserタイプの属性名を見つける必要があります.keyof オペレータを用いて、すべての属性名文字列を含む結合属性を取得することができる.type UserKeys = keyof User;_// :_type UserKeys = "id" | "name" | "email";そして、結合属性の中の文字列の文字列の字面量を取り除く能力が必要です.​User​のタイプを例に挙げると、 ​"id" | "name" | "email"​から​"email"​を削除したいです.私たちは​Excludeヘルプタイプでこの仕事をすることができます.type UserKeysWithoutEmail = Exclude;_// :_type UserKeysWithoutEmail = Exclude< "id" | "name" | "email", "email">;_// :_type UserKeysWithoutEmail = "id" | "name";​Excludeは、lib.s 5.d.tsの中でこのように定義されている./** * Exclude from T those types that are assignable to U */type Exclude = T extends U ? never : T;条件の種類never タイプを使っています.​Excludeを使用して、実際には、私たちは、マッチング"id" | "name" | "email"​タイプのタイプをタイプ別 ​"email"​から取り除く. ​"email"​タイプにマッチしたのは ​"email"​だけです.だから、残りは?
最後に、Userタイプの属性サブセットを含むオブジェクトタイプを創意する必要があります.具体的には、オブジェクトのタイプを作成するということですが、その属性はすべてユニオンタイプのUserKeys WithoutEmailにあります.私たちはPickヘルプタイプで対応する属性名をすべて選び出すことができます.type UserWithoutEmail = Pick;// :type UserWithoutEmail = Pick;// :type UserWithoutEmail = {id: string;name: string;};Pickヘルプタイプはこのように定義されています./** * From T, pick a set of properties whose keys are in the union K */type Pick = {  [P in K]: T[P];};Pickヘルプタイプは、keyofオペレータとマップのタイプ 索引の種類を用いてタイプオブジェクトタイプTの属性Pを取得するT[P]である.
ここでは、上記のkeyof、Exclude、Pick全体を合成します.type UserWithoutEmail = Pick>;注意すべきなのは、このような書き方は私達が定義したUserタイプにしか適用できません.私たちは他のところに使えるようにします.type Omit = Pick>;今、私たちはUserWithoutEmailのタイプを計算できます.type UserWithoutEmail = Omit;オブジェクトのキーは文字列、数字またはSymbolしかないので、Kに制約条件を追加できます.type Omit = Pick>;このように直接extens string𞓜numberを拘束するのはちょっとくどいです.keyof anyで実現できます.等価です.type Omit = Pick>;そこで私達は今完成しました.私たちはもうlib.s 5.d.tsで定義されたOmitタイプを実現しました._/**__* Construct a_ _type_ _with the properties of T except_ _for_ _those in_ _type_ _K.__ */_type Omit = Pick>;Omitを分解する
以下のコードは逐次分解されるOmitタイプです.各ステップに従ってみて、Type Scriptはどのように最終的なタイプを計算しますか?type User = {id: string;name: string;email: string;};type UserWithoutEmail = Omit;// :type UserWithoutEmail = Pick<  User,Exclude>;// :type UserWithoutEmail = Pick<  User,  Exclude>;// :type UserWithoutEmail = Pick<  User,  | ("id" extends "email" ? never : "id")  | ("name" extends "email" ? never : "name")  | ("email" extends "email" ? never : "email")>;// :type UserWithoutEmail = Pick;// :type UserWithoutEmail = Pick;// :type UserWithoutEmail = {[P in "id" | "name"]: User[P];};// :type UserWithoutEmail = {  id: User["id"];  name: User["name"];};// :type UserWithoutEmail = {id: string;name: string;};私たちのUserWithoutEmailタイプ.