Ts高級類型(Utility Types)

學習TypeScript的過程中發(fā)現(xiàn)對某些UtilityTypes不是很理解,就重新在文檔上系統(tǒng)學習了一遍株灸,TypeScript提供了幾種實用工具類型來促進常見的類型轉換崇摄,這些實用程序是全局可用的。

UtilityTypes文檔鏈接:https://www.typescriptlang.org/docs/handbook/utility-types.html

Partial<T>

將泛型傳入的T中所有屬性轉換為可選屬性慌烧,返回的類型可以是T的任意子集逐抑。

interface Person {
  name: string,
  age: number
}

// 相當于type Person1 = { name?: string; age?: number; }
type Person1 = Partial<Person> 

const p: Person = {
  name: 'lin',
  age: 18
}

const p1: Person1 = {
  name: 'lin'
}

源碼:

type Partial<T> = {
    [P in keyof T]?: T[P];
};

keyof T 獲取T中的key值組合,這里的例子T是Person相當于是'name' | 'age', in關鍵字遍歷keyof返回值為新的類型新增了name和age屬性屹蚊,厕氨?操作符將所有屬性定義為可選屬性。

Required <T>

將泛型傳入的T中所有屬性轉換為必須屬性汹粤,和Partial類型相反命斧。

interface Person {
  name?: string,
  age?: number
}

type Person1 = Required<Person> // 相當于type Person1 = { name: string; age: number; }

const p: Person = {
  name: 'lin'
}

// 錯誤提示:類型 "{ name: string; }" 中缺少屬性 "age",但類型 "Required<Person>" 中需要該屬性嘱兼。
const p1: Person1 = {
  name: 'lin'
}

源碼:

type Required<T> = {
    [P in keyof T]-?: T[P];
};

和Partial相反国葬,通過-?操作符將所以可選屬性去除芹壕。

Readonly<T>

將泛型傳入的T中所有屬性轉換為只讀屬性汇四。

interface Person {
  name: string
}

type Person1 = Readonly<Person> // 相當于type Person1 = { readonly name: string; }

const p: Person1 = {
  name: 'lin'
}

// 提示錯誤: 無法分配到 "name" ,因為它是只讀屬性踢涌。
p.name = 'zhen'

源碼:

type Readonly<T> = {
    readonly [P in keyof T]: T[P];
};

使用readonly關鍵字將所有屬性變成只讀屬性通孽。

Record<K, T>

創(chuàng)建一個對象類型,使對象的鍵key的類型為傳入的泛型K睁壁,使對象的值value的類型為傳入的泛型T背苦。

interface CatInfo {
  age: number;
  breed: string;
}

type CatName = "miffy" | "boris" | "mordred";

const cats: Record<CatName, CatInfo> = {
  miffy: { age: 10, breed: "Persian" },
  boris: { age: 5, breed: "Maine Coon" },
  mordred: { age: 16, breed: "British Shorthair" },
};

// boris類型為:CatInfo
cats.boris;

源碼:

type Record<K extends keyof any, T> = {
    [P in K]: T;
};

Pick<T, K>

通過傳入的泛型T中選擇一組屬性K(字符串字面值或字符串字面值的聯(lián)合)來構造類型。

interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

// 相當于type TodoPreview = { title: string; completed: boolean; }
type TodoPreview = Pick<Todo, "title" | "completed">;

const todo: TodoPreview = {
  title: "Clean room",
  completed: false,
};

源碼:

type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};

規(guī)定了泛型K必須是泛型T中key的子集堡僻,上面例子中K必須是‘title’|‘description’|‘completed’

Omit<T,K>

通過傳入的泛型T中選擇一組屬性K并刪除其他屬性糠惫,和Pick相反。

interface Todo {
  title: string;
  description: string;
  completed: boolean;
  createdAt: number;
}
// 相當于 type TodoPreview = { title: string; completed: boolean; createdAt: number; }
type TodoPreview = Omit<Todo, "description">;

const todo: TodoPreview = {
  title: "Clean room",
  completed: false,
  createdAt: 1615544252770,
};

源碼:

type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

結合了Pick和Exclude钉疫,使用Exclude排除掉T中除了包含K的所有屬性硼讽,使用Pick重新創(chuàng)建一個新的類型。

Parameters<T>

從函數(shù)類型T的形參中使用的類型構造元組類型牲阁,可以用來獲取一個函數(shù)里面參數(shù)的類型固阁,不過注意是用元組的形式獲取。

const fn = (a: string, b: number): void => {}

const fn1 = <T>(arg: T): T => arg

// type p1 = [a: string, b: number
type p1 = Parameters<typeof fn>

// type p2 = [arg: unknown]
type p2 = Parameters<typeof fn1>

// type p3 = unknown[]
type p3 = Parameters<any>

// type p4 = never
type p4 = Parameters<never>

// 類型“string”不滿足約束“(...args: any) => any”城菊。
// 泛型必須傳入的是函數(shù)的類型定義
type p5 = Parameters<'lin'>

源碼:

type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;

ReturnType<T>

獲取函數(shù)類型T返回值的類型备燃。

const fn = () => {
  return {
    name: 'lin',
    age: 18
  }
}

const fn1 = () => {
  return [18, 'lin']
}

// type r1 = { name: string; age: number; }
type r1 = ReturnType<typeof fn>

// type r2 = (string | number)[]
type r2= ReturnType<typeof fn1>

// type r3 = any
type r3 = ReturnType<any>

// type r4 = never
type r4 = ReturnType<never>

// 類型“string”不滿足約束“(...args: any) => any”。
// 泛型必須傳入的是函數(shù)的類型定義
type r5 = ReturnType<'lin'>

源碼:

type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末凌唬,一起剝皮案震驚了整個濱河市并齐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖况褪,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撕贞,死亡現(xiàn)場離奇詭異,居然都是意外死亡测垛,警方通過查閱死者的電腦和手機捏膨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來食侮,“玉大人号涯,你說我怎么就攤上這事【馄撸” “怎么了链快?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長眉尸。 經常有香客問我久又,道長,這世上最難降的妖魔是什么效五? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任地消,我火速辦了婚禮,結果婚禮上畏妖,老公的妹妹穿的比我還像新娘脉执。我一直安慰自己,他們只是感情好戒劫,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布半夷。 她就那樣靜靜地躺著,像睡著了一般迅细。 火紅的嫁衣襯著肌膚如雪巫橄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天茵典,我揣著相機與錄音湘换,去河邊找鬼。 笑死统阿,一個胖子當著我的面吹牛彩倚,可吹牛的內容都是我干的。 我是一名探鬼主播扶平,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼帆离,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了结澄?” 一聲冷哼從身側響起哥谷,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤岸夯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后们妥,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體囱修,經...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年王悍,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片餐曼。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡压储,死狀恐怖,靈堂內的尸體忽然破棺而出源譬,到底是詐尸還是另有隱情集惋,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布踩娘,位于F島的核電站刮刑,受9級特大地震影響,放射性物質發(fā)生泄漏养渴。R本人自食惡果不足惜雷绢,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望理卑。 院中可真熱鬧翘紊,春花似錦、人聲如沸藐唠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宇立。三九已至踪宠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間妈嘹,已是汗流浹背柳琢。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留润脸,地道東北人染厅。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像津函,于是被迫代替她去往敵國和親肖粮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內容