TypeScript 高級(jí)類型及用法
點(diǎn)擊上方?前端瓶子君,關(guān)注公眾號(hào)
回復(fù)算法,加入前端編程面試算法每日一題群

本文詳細(xì)介紹了 TypeScript 高級(jí)類型的使用場(chǎng)景,對(duì)日常 TypeScript 的使用可以提供一些幫助。
前言
本文已收錄在 Github: github.com/beichensky/…[1] 中,走過(guò)路過(guò)點(diǎn)個(gè) Star 唄
一、高級(jí)類型
交叉類型(&)
交叉類型是將多個(gè)類型合并為一個(gè)類型。這讓我們可以把現(xiàn)有的多種類型疊加到一起成為一種類型,它包含了所需的所有類型的特性。
語(yǔ)法:
T & U其返回類型既要符合
T類型也要符合U類型用法:假設(shè)有兩個(gè)接口:一個(gè)是 Ant螞蟻接口,一個(gè)是Fly飛翔接口,現(xiàn)在有一只會(huì)飛的螞蟻:
interface?Ant?{
????name:?string;
????weight:?number;
}
interface?Fly?{
????flyHeight:?number;
????speed:?number;
}
//?少了任何一個(gè)屬性都會(huì)報(bào)錯(cuò)
const?flyAnt:?Ant?&?Fly?=?{
????name:?'螞蟻呀嘿',
????weight:?0.2,
????flyHeight:?20,
????speed:?1,
};
復(fù)制代碼
聯(lián)合類型(|)
聯(lián)合類型與交叉類型很有關(guān)聯(lián),但是使用上卻完全不同。
語(yǔ)法:
T | U其返回類型為連接的多個(gè)類型中的任意一個(gè)
用法:假設(shè)聲明一個(gè)數(shù)據(jù),既可以是 string類型,也可以是number類型
let?stringOrNumber:?string?|?number?=?0
stringOrNumber?=?''
復(fù)制代碼
再看下面這個(gè)例子,start 函數(shù)的參數(shù)類型既是 Bird | Fish,那么在 start 函數(shù)中,想要直接調(diào)用的話,只能調(diào)用 Bird 和 Fish 都具備的方法,否則編譯會(huì)報(bào)錯(cuò)
class?Bird?{
????fly()?{
????????console.log('Bird?flying');
????}
????layEggs()?{
????????console.log('Bird?layEggs');
????}
}
class?Fish?{
????swim()?{
????????console.log('Fish?swimming');
????}
????layEggs()?{
????????console.log('Fish?layEggs');
????}
}
const?bird?=?new?Bird();
const?fish?=?new?Fish();
function?start(pet:?Bird?|?Fish)?{
????//?調(diào)用?layEggs?沒(méi)問(wèn)題,因?yàn)?Bird?或者?Fish?都有?layEggs?方法
????pet.layEggs();
????//?會(huì)報(bào)錯(cuò):Property 'fly' does not exist on type 'Bird | Fish'
????//?pet.fly();
????//?會(huì)報(bào)錯(cuò):Property 'swim' does not exist on type 'Bird | Fish'
????//?pet.swim();
}
start(bird);
start(fish);
復(fù)制代碼
二、關(guān)鍵字
類型約束(extends)
語(yǔ)法:T extends K
這里的 extends 不是類、接口的繼承,而是對(duì)于類型的判斷和約束,意思是判斷 T 能否賦值給 K
可以在泛型中對(duì)傳入的類型進(jìn)行約束
const?copy?=?(value:?string?|?number):?string?|?number?=>?value
//?只能傳入?string?或者?number
copy(10)
//?會(huì)報(bào)錯(cuò):Argument of type 'boolean' is not assignable to parameter of type 'string | number'
//?copy(false)
復(fù)制代碼
也可以判斷 T 是否可以賦值給 U,可以的話返回 T,否則返回 never
type?Exclude?=?T?extends?U???T?:?never;
復(fù)制代碼
類型映射(in)
會(huì)遍歷指定接口的 key 或者是遍歷聯(lián)合類型
interface?Person?{
????name:?string
????age:?number
????gender:?number
}
//?將?T?的所有屬性轉(zhuǎn)換為只讀類型
type?ReadOnlyType?=?{
????readonly?[P?in?keyof?T]:?T
}
//?type?ReadOnlyPerson?=?{
//?????readonly?name:?Person;
//?????readonly?age:?Person;
//?????readonly?gender:?Person;
//?}
type?ReadOnlyPerson?=?ReadOnlyType
復(fù)制代碼
類型謂詞(is)
語(yǔ)法:
parameterName is TypeparameterName必須是來(lái)自于當(dāng)前函數(shù)簽名里的一個(gè)參數(shù)名,判斷 parameterName 是否是 Type 類型。
具體的應(yīng)用場(chǎng)景可以跟著下面的代碼思路進(jìn)行使用:
看完聯(lián)合類型的例子后,可能會(huì)考慮:如果想要在 start 函數(shù)中,根據(jù)情況去調(diào)用 Bird 的 fly 方法和 Fish 的 swim 方法,該如何操作呢?
首先想到的可能是直接檢查成員是否存在,然后進(jìn)行調(diào)用:
function?start(pet:?Bird?|?Fish)?{
????//?調(diào)用?layEggs?沒(méi)問(wèn)題,因?yàn)?Bird?或者?Fish?都有?layEggs?方法
????pet.layEggs();
????if?((pet?as?Bird).fly)?{
????????(pet?as?Bird).fly();
????}?else?if?((pet?as?Fish).swim)?{
????????(pet?as?Fish).swim();
????}
}
復(fù)制代碼
但是這樣做,判斷以及調(diào)用的時(shí)候都要進(jìn)行類型轉(zhuǎn)換,未免有些麻煩,可能會(huì)想到寫個(gè)工具函數(shù)判斷下:
function?isBird(bird:?Bird?|?Fish):?boolean?{
????return?!!(bird?as?Bird).fly;
}
function?isFish(fish:?Bird?|?Fish):?boolean?{
????return?!!(fish?as?Fish).swim;
}
function?start(pet:?Bird?|?Fish)?{
????//?調(diào)用?layEggs?沒(méi)問(wèn)題,因?yàn)?Bird?或者?Fish?都有?layEggs?方法
????pet.layEggs();
????if?(isBird(pet))?{
????????(pet?as?Bird).fly();
????}?else?if?(isFish(pet))?{
????????(pet?as?Fish).swim();
????}
}
復(fù)制代碼
看起來(lái)簡(jiǎn)潔了一點(diǎn),但是調(diào)用方法的時(shí)候,還是要進(jìn)行類型轉(zhuǎn)換才可以,否則還是會(huì)報(bào)錯(cuò),那有什么好的辦法,能讓我們判斷完類型之后,就可以直接調(diào)用方法,不用再進(jìn)行類型轉(zhuǎn)換呢?
OK,肯定是有的,類型謂詞 is 就派上用場(chǎng)了
用法:
function?isBird(bird:?Bird?|?Fish):?bird?is?Bird?{
????return?!!(bird?as?Bird).fly
}
function?start(pet:?Bird?|?Fish)?{
????//?調(diào)用?layEggs?沒(méi)問(wèn)題,因?yàn)?Bird?或者?Fish?都有?layEggs?方法
????pet.layEggs();
????if?(isBird(pet))?{
????????pet.fly();
????}?else?{
????????pet.swim();
????}
};
復(fù)制代碼
每當(dāng)使用一些變量調(diào)用 isFish 時(shí),TypeScript 會(huì)將變量縮減為那個(gè)具體的類型,只要這個(gè)類型與變量的原始類型是兼容的。
TypeScript 不僅知道在 if 分支里 pet 是 Fish 類型;它還清楚在 else 分支里,一定不是 Fish 類型,一定是 Bird 類型
待推斷類型(infer)
可以用 infer P 來(lái)標(biāo)記一個(gè)泛型,表示這個(gè)泛型是一個(gè)待推斷的類型,并且可以直接使用
比如下面這個(gè)獲取函數(shù)參數(shù)類型的例子:
type?ParamType?=?T?extends?(param:?infer?P)?=>?any???P?:?T;
type?FunctionType?=?(value:?number)?=>?boolean
type?Param?=?ParamType;???//?type?Param?=?number
type?OtherParam?=?ParamType;???//?type?Param?=?symbol
復(fù)制代碼
判斷 T 是否能賦值給 (param: infer P) => any,并且將參數(shù)推斷為泛型 P,如果可以賦值,則返回參數(shù)類型 P,否則返回傳入的類型
再來(lái)一個(gè)獲取函數(shù)返回類型的例子:
type?ReturnValueType?=?T?extends?(param:?any)?=>?infer?U???U?:?T;
type?FunctionType?=?(value:?number)?=>?boolean
type?Return?=?ReturnValueType;???//?type?Return?=?boolean
type?OtherReturn?=?ReturnValueType<number>;???//?type?OtherReturn?=?number
復(fù)制代碼
判斷 T 是否能賦值給 (param: any) => infer U,并且將返回值類型推斷為泛型 U,如果可以賦值,則返回返回值類型 P,否則返回傳入的類型
原始類型保護(hù)(typeof)
語(yǔ)法: typeof v === "typename"或typeof v !== "typename"
用來(lái)判斷數(shù)據(jù)的類型是否是某個(gè)原始類型(
number、string、boolean、symbol)并進(jìn)行類型保護(hù)
"typename"必須是 "number", "string", "boolean"或 "symbol"。但是 TypeScript 并不會(huì)阻止你與其它字符串比較,語(yǔ)言不會(huì)把那些表達(dá)式識(shí)別為類型保護(hù)。
看下面這個(gè)例子, print 函數(shù)會(huì)根據(jù)參數(shù)類型打印不同的結(jié)果,那如何判斷參數(shù)是 string 還是 number 呢?
function?print(value:?number?|?string)?{
????//?如果是?string?類型
????//?console.log(value.split('').join(',?'))
????//?如果是?number?類型
????//?console.log(value.toFixed(2))
}
復(fù)制代碼
有兩種常用的判斷方式:
根據(jù)是否包含
split屬性判斷是string類型,是否包含toFixed方法判斷是number類型弊端:不論是判斷還是調(diào)用都要進(jìn)行類型轉(zhuǎn)換
使用類型謂詞
is弊端:每次都要去寫一個(gè)工具函數(shù),太麻煩了
用法:這就到了 typeof一展身手的時(shí)候了
function?print(value:?number?|?string)?{
????if?(typeof?value?===?'string')?{
????????console.log(value.split('').join(',?'))
????}?else?{
????????console.log(value.toFixed(2))
????}
}
復(fù)制代碼
使用 typeof 進(jìn)行類型判斷后,TypeScript 會(huì)將變量縮減為那個(gè)具體的類型,只要這個(gè)類型與變量的原始類型是兼容的。
類型保護(hù)(instanceof)
與 typeof 類似,不過(guò)作用方式不同,instanceof 類型保護(hù)是通過(guò)構(gòu)造函數(shù)來(lái)細(xì)化類型的一種方式。
instanceof 的右側(cè)要求是一個(gè)構(gòu)造函數(shù),TypeScript 將細(xì)化為:
此構(gòu)造函數(shù)的 prototype屬性的類型,如果它的類型不為any的話構(gòu)造簽名所返回的類型的聯(lián)合
還是以 類型謂詞 is 示例中的代碼做演示:
最初代碼:
function?start(pet:?Bird?|?Fish)?{
????//?調(diào)用?layEggs?沒(méi)問(wèn)題,因?yàn)?Bird?或者?Fish?都有?layEggs?方法
????pet.layEggs();
????if?((pet?as?Bird).fly)?{
????????(pet?as?Bird).fly();
????}?else?if?((pet?as?Fish).swim)?{
????????(pet?as?Fish).swim();
????}
}
復(fù)制代碼
使用 instanceof 后的代碼:
function?start(pet:?Bird?|?Fish)?{
????//?調(diào)用?layEggs?沒(méi)問(wèn)題,因?yàn)?Bird?或者?Fish?都有?layEggs?方法
????pet.layEggs();
????if?(pet?instanceof?Bird)?{
????????pet.fly();
????}?else?{
????????pet.swim();
????}
}
復(fù)制代碼
可以達(dá)到相同的效果
索引類型查詢操作符(keyof)
語(yǔ)法: keyof T
對(duì)于任何類型
T,keyof T的結(jié)果為T上已知的 公共屬性名 的 聯(lián)合
interface?Person?{
????name:?string;
????age:?number;
}
type?PersonProps?=?keyof?Person;?//?'name'?|?'age'
復(fù)制代碼
這里,keyof Person 返回的類型和 'name' | 'age' 聯(lián)合類型是一樣,完全可以互相替換
用法: keyof只能返回類型上已知的 公共屬性名
class?Animal?{
????type:?string;
????weight:?number;
????private?speed:?number;
}
type?AnimalProps?=?keyof?Animal;?//?"type"?|?"weight"
復(fù)制代碼
例如我們經(jīng)常會(huì)獲取對(duì)象的某個(gè)屬性值,但是不確定是哪個(gè)屬性,這個(gè)時(shí)候可以使用 extends 配合 typeof 對(duì)屬性名進(jìn)行限制,限制傳入的參數(shù)只能是對(duì)象的屬性名
const?person?=?{
????name:?'Jack',
????age:?20
}
function?getPersonValue<T?extends?keyof?typeof?person>(fieldName:?keyof?typeof?person)?{
????return?person[fieldName]
}
const?nameValue?=?getPersonValue('name')
const?ageValue?=?getPersonValue('age')
//?會(huì)報(bào)錯(cuò):Argument of type '"gender"' is not assignable to parameter of type '"name"?|?"age"'
//?getPersonValue('gender')
復(fù)制代碼
索引訪問(wèn)操作符(T[K])
語(yǔ)法: T[K]
類似于
js中使用對(duì)象索引的方式,只不過(guò)js中是返回對(duì)象屬性的值,而在ts中返回的是T對(duì)應(yīng)屬性 P 的類型
用法:
interface?Person?{
????name:?string
????age:?number
????weight:?number?|?string
????gender:?'man'?|?'women'
}
type?NameType?=?Person['name']??//?string
type?WeightType?=?Person['weight']??//?string?|?number
type?GenderType?=?Person['gender']??//?"man"?|?"women"
復(fù)制代碼
三、映射類型
只讀類型(Readonly)
定義:
type?Readonly?=?{
????readonly?[P?in?keyof?T]:?T[P];
}
復(fù)制代碼
用于將
T類型的所有屬性設(shè)置為只讀狀態(tài)。
用法:
interface?Person?{
????name:?string
????age:?number
}
const?person:?Readonly?=?{
????name:?'Lucy',
????age:?22
}
//?會(huì)報(bào)錯(cuò):Cannot assign to 'name' because it is a read-only property
person.name?=?'Lily'
復(fù)制代碼
readonly只讀, 被readonly標(biāo)記的屬性只能在聲明時(shí)或類的構(gòu)造函數(shù)中賦值,之后將不可改(即只讀屬性)
只讀數(shù)組(ReadonlyArray)
定義:
interface?ReadonlyArray?{
????/**?Iterator?of?values?in?the?array.?*/
????[Symbol.iterator]():?IterableIterator;
????/**
?????*?Returns?an?iterable?of?key,?value?pairs?for?every?entry?in?the?array
?????*/
????entries():?IterableIterator<[number,?T]>;
????/**
?????*?Returns?an?iterable?of?keys?in?the?array
?????*/
????keys():?IterableIterator<number>;
????/**
?????*?Returns?an?iterable?of?values?in?the?array
?????*/
????values():?IterableIterator;
}
復(fù)制代碼
只能在數(shù)組初始化時(shí)為變量賦值,之后數(shù)組無(wú)法修改
使用:
interface?Person?{
????name:?string
}
const?personList:?ReadonlyArray?=?[{?name:?'Jack'?},?{?name:?'Rose'?}]
//?會(huì)報(bào)錯(cuò):Property 'push' does not exist on type 'readonly Person[]'
//?personList.push({?name:?'Lucy'?})
//?但是內(nèi)部元素如果是引用類型,元素自身是可以進(jìn)行修改的
personList[0].name?=?'Lily'
復(fù)制代碼
可選類型(Partial)
用于將 T 類型的所有屬性設(shè)置為可選狀態(tài),首先通過(guò) keyof T,取出類型 T 的所有屬性, 然后通過(guò) in 操作符進(jìn)行遍歷,最后在屬性后加上 ?,將屬性變?yōu)榭蛇x屬性。
定義:
type?Partial?=?{
????[P?in?keyof?T]?:?T[P];
}
復(fù)制代碼
用法:
interface?Person?{
????name:?string
????age:?number
}
//?會(huì)報(bào)錯(cuò):Type '{}' is missing the following properties from type 'Person': name, age
//?let?person:?Person?=?{}
//?使用?Partial?映射后返回的新類型,name?和?age?都變成了可選屬性
let?person:?Partial?=?{}
person?=?{?name:?'pengzu',?age:?800?}
person?=?{?name:?'z'?}
person?=?{?age:?18?}
復(fù)制代碼
必選類型(Required)
和 Partial 的作用相反
用于將 T 類型的所有屬性設(shè)置為必選狀態(tài),首先通過(guò) keyof T,取出類型 T 的所有屬性, 然后通過(guò) in 操作符進(jìn)行遍歷,最后在屬性后的 ? 前加上 -,將屬性變?yōu)楸剡x屬性。
定義:
type?Required?=?{
????[P?in?keyof?T]-?:?T[P];
}
復(fù)制代碼
使用:
interface?Person?{
????name?:?string
????age?:?number
}
//?使用?Required?映射后返回的新類型,name?和?age?都變成了必選屬性
//?會(huì)報(bào)錯(cuò):Type '{}' is missing the following properties from type 'Required': name, age
let?person:?Required?=?{}
復(fù)制代碼
提取屬性(Pick)
定義:
type?Pickextends?keyof?T>?=?{
????[P?in?K]:?T[P];
}
復(fù)制代碼
從
T類型中提取部分屬性,作為新的返回類型。
使用:比如我們?cè)诎l(fā)送網(wǎng)絡(luò)請(qǐng)求時(shí),只需要傳遞類型中的部分屬性,就可以通過(guò) Pick來(lái)實(shí)現(xiàn)。
interface?Goods?{
????type:?string
????goodsName:?string
????price:?number
}
//?作為網(wǎng)絡(luò)請(qǐng)求參數(shù),只需要?goodsName?和?price?就可以
type?RequestGoodsParams?=?Pick'goodsName'?|?'price'>
//?返回類型:
//?type?RequestGoodsParams?=?{
//?????goodsName:?string;
//?????price:?number;
//?}
const?params:?RequestGoodsParams?=?{
????goodsName:?'',
????price:?10
}
復(fù)制代碼
排除屬性(Omit)
定義:
type Omit= Pick > 和
Pick作用相反,用于從T類型中,排除部分屬性用法:比如長(zhǎng)方體有長(zhǎng)寬高,而正方體長(zhǎng)寬高相等,所以只需要長(zhǎng)就可以,那么此時(shí)就可以用 Omit來(lái)生成正方體的類型
interface?Rectangular?{
????length:?number
????height:?number
????width:?number
}
type?Square?=?Omit'height'?|?'width'>
//?返回類型:
//?type?Square?=?{
//?????length:?number;
//?}
const?temp:?Square?=?{?length:?5?}
復(fù)制代碼
摘取類型(Extract)
語(yǔ)法:
Extract提取
T中可以 賦值 給U的類型定義:
type Extract= T extends U ? T : never; 用法:
type?T01?=?Extract<"a"?|?"b"?|?"c"?|?"d",?"a"?|?"c"?|?"f">;??//?"a"?|?"c"
type?T02?=?Extract<string?|?number?|?(()?=>?void),?Function>;??//?()?=>?void
復(fù)制代碼
排除類型(Exclude)
語(yǔ)法:
Exclude與
Extract用法相反,從T中剔除可以賦值給U的類型定義:
type Exclude= T extends U ? never : T 用法:
type?T00?=?Exclude<"a"?|?"b"?|?"c"?|?"d",?"a"?|?"c"?|?"f">;??//?"b"?|?"d"
type?T01?=?Exclude<string?|?number?|?(()?=>?void),?Function>;??//?string?|?number
復(fù)制代碼
屬性映射(Record)
定義:
type?Recordextends?string?|?number?|?symbol,?T>?=?{
????[P?in?K]:?T;
}
復(fù)制代碼
接收兩個(gè)泛型,
K必須可以是可以賦值給string | number | symbol的類型,通過(guò)in操作符對(duì)K進(jìn)行遍歷,每一個(gè)屬性的類型都必須是T類型
用法:比如我們想要將 Person類型的數(shù)組轉(zhuǎn)化成對(duì)象映射,可以使用Record來(lái)指定映射對(duì)象的類型
interface?Person?{
????name:?string
????age:?number
}
const?personList?=?[
????{?name:?'Jack',?age:?26?},
????{?name:?'Lucy',?age:?22?},
????{?name:?'Rose',?age:?18?},
]
const?personMap:?Record<string,?Person>?=?{}
personList.map((person)?=>?{
????personMap[person.name]?=?person
})
復(fù)制代碼
比如在傳遞參數(shù)時(shí),希望參數(shù)是一個(gè)對(duì)象,但是不確定具體的類型,就可以使用 Record 作為參數(shù)類型
function?doSomething(obj:?Record<string,?any>)?{
}
復(fù)制代碼
不可為空類型(NonNullable)
定義: type NonNullable= T extends null | undefined ? never : T
從 T 中剔除
null、undefined、never類型,不會(huì)剔除void、unknow類型
type?T01?=?NonNullable<string?|?number?|?undefined>;??//?string?|?number
type?T02?=?NonNullable<(()?=>?string)?|?string[]?|?null?|?undefined>;??//?(()?=>?string)?|?string[]
type?T03?=?NonNullable<{name?:?string,?age:?number}?|?string[]?|?null?|?undefined>;??//?{name?:?string,?age:?number}?|?string[]
復(fù)制代碼
構(gòu)造函數(shù)參數(shù)類型(ConstructorParameters)
返回 class 中構(gòu)造函數(shù)參數(shù)類型組成的 元組類型
定義:
/**
?*?Obtain?the?parameters?of?a?constructor?function?type?in?a?tuple
?*/
type?ConstructorParametersextends?new?(...args:?any)?=>?any>?=?T?extends?new?(...args:?infer?P)?=>?any???P?:?never;
復(fù)制代碼
使用:
class?Person?{
????name:?string
????age:?number
????weight:?number
????gender:?'man'?|?'women'
????constructor(name:?string,?age:?number,?gender:?'man'?|?'women')?{
????????this.name?=?name
????????this.age?=?age;
????????this.gender?=?gender
????}
}
type?ConstructorType?=?ConstructorParameters<typeof?Person>??//??[name:?string,?age:?number,?gender:?"man"?|?"women"]
const?params:?ConstructorType?=?['Jack',?20,?'man']
復(fù)制代碼
實(shí)例類型(InstanceType)
獲取 class 構(gòu)造函數(shù)的返回類型
定義:
/**
?*?Obtain?the?return?type?of?a?constructor?function?type
?*/
type?InstanceTypeextends?new?(...args:?any)?=>?any>?=?T?extends?new?(...args:?any)?=>?infer?R???R?:?any;
復(fù)制代碼
使用:
class?Person?{
????name:?string
????age:?number
????weight:?number
????gender:?'man'?|?'women'
????constructor(name:?string,?age:?number,?gender:?'man'?|?'women')?{
????????this.name?=?name
????????this.age?=?age;
????????this.gender?=?gender
????}
}
type?Instance?=?InstanceType<typeof?Person>??//?Person
const?params:?Instance?=?{
????name:?'Jack',
????age:?20,
????weight:?120,
????gender:?'man'
}
復(fù)制代碼
函數(shù)參數(shù)類型(Parameters)
獲取函數(shù)的參數(shù)類型組成的 元組
定義:
/**
?*?Obtain?the?parameters?of?a?function?type?in?a?tuple
?*/
type?Parametersextends?(...args:?any)?=>?any>?=?T?extends?(...args:?infer?P)?=>?any???P?:?never;
復(fù)制代碼
用法:
type?FunctionType?=?(name:?string,?age:?number)?=>?boolean
type?FunctionParamsType?=?Parameters??//?[name:?string,?age:?number]
const?params:??FunctionParamsType?=?['Jack',?20]
復(fù)制代碼
函數(shù)返回值類型(ReturnType)
獲取函數(shù)的返回值類型
定義:
/**
?*?Obtain?the?return?type?of?a?function?type
?*/
type?ReturnTypeextends?(...args:?any)?=>?any>?=?T?extends?(...args:?any)?=>?infer?R???R?:?any;
復(fù)制代碼
使用:
type?FunctionType?=?(name:?string,?age:?number)?=>?boolean?|?string
type?FunctionReturnType?=?ReturnType??//?boolean?|?string
復(fù)制代碼
四、總結(jié)
高級(jí)類型
用法 描述 & 交叉類型,將多個(gè)類型合并為一個(gè)類型,交集 \ 聯(lián)合類型,將多個(gè)類型組合成一個(gè)類型,可以是多個(gè)類型的任意一個(gè),并集 關(guān)鍵字
用法 描述 T extends U 類型約束,判斷 T 是否可以賦值給 U P in T 類型映射,遍歷 T 的所有類型 parameterName is Type 類型謂詞,判斷函數(shù)參數(shù) parameterName 是否是 Type 類型 infer P 待推斷類型,使用 infer 標(biāo)記類型 P,就可以使用待推斷的類型 P typeof v === "typename" 原始類型保護(hù),判斷數(shù)據(jù)的類型是否是某個(gè)原始類型( number、string、boolean、symbol)instanceof v 類型保護(hù),判斷數(shù)據(jù)的類型是否是構(gòu)造函數(shù)的 prototype屬性類型keyof 索引類型查詢操作符,返回類型上已知的 公共屬性名 T[K] 索引訪問(wèn)操作符,返回 T對(duì)應(yīng)屬性 P 的類型映射類型
用法 描述 Readonly 將 T 中所有屬性都變?yōu)橹蛔x ReadonlyArray 返回一個(gè) T 類型的只讀數(shù)組 ReadonlyMap 返回一個(gè) T 和 U 類型組成的只讀 Map Partial 將 T 中所有的屬性都變成可選類型 Required 將 T 中所有的屬性都變成必選類型 Pick 從 T 中摘取部分屬性 Omit 從 T 中排除部分屬性 Exclude 從 T 中剔除可以賦值給 U 的類型 Extract 提取 T 中可以賦值給 U 的類型 Record 返回屬性名為 K,屬性值為 T 的類型 NonNullable 從 T 中剔除 null 和 undefined ConstructorParameters 獲取 T 的構(gòu)造函數(shù)參數(shù)類型組成的元組 InstanceType 獲取 T 的實(shí)例類型 Parameters 獲取函數(shù)參數(shù)類型組成的元組 ReturnType 獲取函數(shù)返回值類型
寫在后面
如果有寫的不對(duì)或不嚴(yán)謹(jǐn)?shù)牡胤剑瑲g迎大家能提出寶貴的意見(jiàn),十分感謝。
如果喜歡或者有所幫助,歡迎 Star,對(duì)作者也是一種鼓勵(lì)和支持
關(guān)于本文
作者:暖生
https://juejin.cn/post/6985296521495314445
