我們來看一下 TypeScript 中的泛型,這也是很多同學(xué)覺得 TypeScript 很難的最大原因。
首先我們看下面的代碼,我們定一個 idientity0 函數(shù),這個函數(shù)邏輯非常簡單,就是直接返回參數(shù),那么我們怎么確定返回值的類型呢?
因為輸入值可以是任意屬性,所以我們只能寫出 identity0 這個函數(shù),參數(shù)和返回值類型都是 any,但是明顯不能滿足我們的需求。我們需要返回值的類型和參數(shù)一致,所以我們在函數(shù)名之后使用 <> 定一個泛型 T,你可以理解這個 T 的意思就是給函數(shù)參數(shù)定義了一個類型變量,會在后面使用,相當(dāng)于【type T = arg 的類型】,返回值使用 T 這個類型就完成了這個需求。
function identity0(arg: any): any {
return arg
}
// 相當(dāng)于type T = arg的類型
function identity<T>(arg: T): T {
return arg
}
identity<string>('玩轉(zhuǎn)vue 3全家桶') // 這個T就是string,所以返回值必須得是string
identity<number>(1)
有了泛型之后,我們就有了把函數(shù)參數(shù)定義成類型的功能,我們就可以實現(xiàn)類似高階函數(shù)的類型函數(shù)。下面的代碼中我們使用 keyof 語法獲得已知類型 VueCourse5 的屬性列表,相當(dāng)于 ‘name’|‘price’:
interface VueCourse5 {
name:string,
price:number
}
type CourseProps = keyof VueCourse5 // 只能是name和price選一個
let k:CourseProps = 'name'
let k1:CourseProps = 'p' // 改成price
keyof 可以幫助我們拆解已有類型,下一步我們需要使用 extends 來實現(xiàn)類型系統(tǒng)中的條件判斷。我們定義類型函數(shù) ExtendsType,接受泛型參數(shù) T 后,通過判斷 T 是不是布爾值來返回不同的類型字符串,我們就可以通過 ExtendsType 傳入不同的參數(shù)去返回不同的類型。
// T extends U ? X : Y 類型三元表達(dá)式
type ExtendsType<T> = T extends boolean ? "重學(xué)前端" : "玩轉(zhuǎn)Vue 3"
type ExtendsType1 = ExtendsType<boolean> // type ExtendsType1='重學(xué)前端'
type ExtendsType2 = ExtendsType<string> // type ExtendsType2='玩轉(zhuǎn)Vue 3'
extends 相當(dāng)于 TypeScript 世界中的條件語句,然后 in 關(guān)鍵字可以理解為 TypeScript 世界中的遍歷。下面的代碼中我們通過 k in Courses 語法,相當(dāng)于遍歷了 Courses 所有的類型作為 CourseObj 的屬性,值的類型是 number。
type Courses = '玩轉(zhuǎn)Vue 3'|'重學(xué)前端'
type CourseObj = {
[k in Courses]:number // 遍歷Courses類型作為key
}
// 上面的代碼等于下面的定義
// type CourseObj = {
// 玩轉(zhuǎn)Vue 3: number;
// 重學(xué)前端: number;
// }
學(xué)完上面的語法,你就能完全搞懂第 18 講里的 getProperty 函數(shù)。限制函數(shù)第二個參數(shù)只能是第一個參數(shù)的屬性,并且返回值的類型,最后我們傳遞不存在的屬性時,TypeScript 就會報錯。文章來源:http://www.zghlxwxcb.cn/news/detail-534442.html
// K extends keyof T限制K的類型必須是T的屬性之一
// T[K]是值得類型
function getProperty<T, K extends keyof T>(o: T, name: K): T[K] {
return o[name]
}
const coursePrice:CourseObj = {
"玩轉(zhuǎn)Vue 3":129,
"重學(xué)前端":129
}
getProperty(coursePrice,'玩轉(zhuǎn)Vue 3')
getProperty(coursePrice,'不學(xué)前端') // 報錯
然后我再給你講解最后一個關(guān)鍵字 infer。?讓我們擁有了給函數(shù)的參數(shù)定義類型變量的能力,infer 則是可以在 extends 之后的變量設(shè)置類型變量,更加細(xì)致地控制類型。下面的代碼中我們定義了 ReturnType 類型函數(shù),目的是返回傳入函數(shù)的返回值類型。infer P 的意思就是泛型 T 是函數(shù)類型,并且這個函數(shù)類型的返回類型是 P。文章來源地址http://www.zghlxwxcb.cn/news/detail-534442.html
type Foo = () => CourseObj
// 如果T是一個函數(shù),并且函數(shù)返回類型是P就返回P
type ReturnType1<T> = T extends ()=>infer P ?P:never
type Foo1 = ReturnType1<Foo>
到了這里,關(guān)于TypeScript 可以進(jìn)行類型編程,這會極大提高 TypeScript 在復(fù)雜場景下的應(yīng)用場景。的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!