假如咱們要實現一個函數,這個函數會返回任何傳入它的值。不用泛型的話就只能使用any或者是用類型推斷。這時用泛型就是一個很好的選擇。ide
function identity<T>(arg: T): T {
return arg;
}
複製代碼
泛型簡單來講就是當你傳進來的參數是string,那麼T在這個執行中就等於string。函數
官方文檔所說ui
never 類型表示的是那些永不存在的值的類型。 例如, never 類型是那些老是會拋出異常或根本就不會有返回值的函數表達式或箭頭函數表達式的返回值類型; 變量也多是 never 類型,當它們被永不爲真的類型保護所約束時。 never 類型是任何類型的子類型,也能夠賦值給任何類型;然而,沒有類型是 never 的子類型或能夠賦值給 never 類型(除了 never 自己以外)。 即便 any 也不能夠賦值給 never。spa
never不能被賦值,並且表明的是沒法到達的終點。也就是說你的程序就不該該執行到這,never的其中一個用法就是收窄類型。code
下面舉個尤大大說的例子,假如你有一個聯合類型文檔
interface Foo {
type: 'foo'
}
interface Bar {
type: 'bar'
}
type All = Foo | Bar
複製代碼
在 switch 當中判斷 type,TS 是能夠收窄類型的 (discriminated union):源碼
function handleValue(val: All) {
switch (val.type) {
case 'foo':
// 這裏 val 被收窄爲 Foo
break
case 'bar':
// val 在這裏是 Bar
break
default:
// val 在這裏是 never
const exhaustiveCheck: never = val
break
}
}
複製代碼
注意在 default 裏面咱們把被收窄爲 never 的 val 賦值給一個顯式聲明爲 never 的變量。若是一切邏輯正確,那麼這裏應該可以編譯經過。可是假如後來有一天你的同事改了 All 的類型:string
type All = Foo | Bar | Baz
複製代碼
然而他忘記了在 handleValue 裏面加上針對 Baz 的處理邏輯,這個時候在 default branch 裏面 val 會被收窄爲 Baz,致使沒法賦值給 never,產生一個編譯錯誤。因此經過這個辦法,你能夠確保 handleValue 老是窮盡 (exhaust) 了全部 All 的可能類型。it
keyof的做用就是取全部的鍵,只取鍵,而且keyof 取到鍵後會保存爲聯合類型。io
interface person {
sex: string;
age: number;
}
type keys = keyof person; // type keys =sex | age
複製代碼
in的做用是遍歷全部的健
type age = 'dog' | 'cat';
type age={
[key in age]:number;
};
/* 至關於
* type age={
* dog:number;
* cat:number;
*/ };
複製代碼
Partial,Required,Readonly這三個比較簡單,因此就一塊兒講了
Partial做用是將屬性變爲可選屬性
type Partial<T> = {
[P in keyof T]?: T[P];
};
複製代碼
用法:
interface Age:{
son:number;
father:number;
};
type person=Partial<Age>
/* person就等於
*interface person:{
* son?:number;
* father?:number;
*/};
複製代碼
下面同理
2. Required做用是將屬性變成必須屬性
type Required<T> = {
[P in keyof T]-?: T[P];
};
複製代碼
Readonly做用是將屬性變成只讀屬性
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
複製代碼
pick是篩選出我想要的屬性。
源碼以下:
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
複製代碼
interface Age:{
son:number;
father:number;
};
type person=Pick<Age,'son'>
/* person就等於
*interface person:{
* son:number;
*/};
複製代碼
pick會在Age中篩選出son的屬性賦值給person
Record將某個類型轉化成目標類型。
官方源碼:
type Record<K extends keyof any, T> = {
[P in K]: T;
};
複製代碼
將K中的每一個屬性([P in K]),都轉爲T類型
interface Age:{
son:number;
father:number;
};
type person=Record<Age,string>
/*
*這時person就等於:
*interface person:{
* son:string;
* father:string;
* };
*/複製代碼