減少 TS 重復(fù)代碼,Omit 用起來真香!
你用過 TypeScript 內(nèi)置的 Omit 工具類型么?你想知道 Omit 的應(yīng)用場景和內(nèi)部是如何實(shí)現(xiàn)的么?如果想的話,閱讀完本文之后,也許你就懂了。這是一個(gè)使用 type 類型別名定義的 User 類型,用于描述用戶對象。
type User = {
id: string; // 用戶id
name: string; // 用戶名
password: string; // 密碼
createdAt: Date; // 創(chuàng)建時(shí)間
updatedAt: Date; // 更新時(shí)間
};
其中 id、createdAt 和 updatedAt 這些屬性是在創(chuàng)建用戶時(shí),由服務(wù)端自動(dòng)生成的。因此在注冊用戶時(shí),用于描述注冊用戶對象的 RegisterUser 類型并不需要以上這些屬性。那么我們應(yīng)該如何高效地定義 RegisterUser 類型呢?這時(shí)我們可以使用 TS 內(nèi)置的 Omit 工具類型。
type RegisterUser = Omit<User, "id" | "createdAt" | "updatedAt">;
type RegisterUser = {
name: string;
password: string;
}
由以上結(jié)果可知,id、createdAt 和 updatedAt 這些屬性都已經(jīng)被過濾掉了,所以使用 Omit 工具類型,我們可以很方便地過濾掉對象類型中不需要的屬性。
其實(shí) Omit 工具類型還有其它的作用,比如我們可以利用接口繼承的方式來實(shí)現(xiàn)覆蓋已有對象類型中已知屬性的類型。具體的實(shí)現(xiàn)方式也很簡單:
interface UserUI extends Omit<User, "createdAt" | "updatedAt"> {
createdAt: string;
updatedAt: string;
}
在以上代碼中,UserUI 接口描述的對象用于在頁面上顯示用戶信息,所以我們把原有 User 類型中 createdAt 和 updatedAt 屬性的類型都修改成 string 類型。
了解完 Omit 工具類型的應(yīng)用場景,下面我們來看一下它內(nèi)部是如何實(shí)現(xiàn)的。
// typescript/lib/lib.es5.d.ts
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
由以上代碼可知,Omit 工具類型內(nèi)部使用了 TS 內(nèi)置的 Pick 和 Exclude 工具類型。
其中 keyof 操作符用于獲取某種類型中的所有鍵,其返回類型是聯(lián)合類型。而 Exclude 工具類型用于實(shí)現(xiàn)類型過濾,即從 keyof T 返回的聯(lián)合類型中,過濾掉要排除的屬性。最終再使用 Pick 工具類型從原有的對象類型中,挑選出需保留的屬性,組合成新的對象類型。