在Vue3 關(guān)于ref的源碼中有這樣一段代碼
export function isRef(r: any): r is Ref {
return !!(r && r.__v_isRef === true)
}
源碼地址:
https://github.com/vuejs/core/blob/main/packages/reactivity/src/ref.ts#L62
這樣的 r is Ref就是自定義守衛(wèi),一般在ts中我們,我們判斷類型,可以用:
- 類型判斷:typeof
- 實(shí)例判斷:instanceof
- 屬性判斷:in
- 字面量相等判斷:==, ===, !=, !==
舉個(gè)例子:
type Person = {
name: string
age?: number
}
// 獲得所有age屬性
function getPersonAges(persons: Person[]): number[] {
return persons.filter(person => person.age !== undefined).map(person => person.age)
}
但是上面的代碼會(huì)報(bào)錯(cuò):
Type '(number | undefined)[]' is not assignable to type 'number[]'.
Type 'number | undefined' is not assignable to type 'number'.
Type 'undefined' is not assignable to type 'number'.
因?yàn)?code>Person[]數(shù)組還是接收了Person類型,我們看filter()源碼,會(huì)發(fā)現(xiàn)這樣一個(gè)重載函數(shù)
filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];
/**
* Returns the elements of an array that meet the condition specified in a callback function.
* @param predicate A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array.
* @param thisArg An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value.
*/
所以上面的代碼可以這樣寫:
type Person = {
name: string
age?: number
}
type FullPerson = Required<Person>
function getPersonAges(persons: Person[]): number[] {
return persons
.filter<FullPerson>((person): person is FullPerson => person.age !== undefined)
.map(person => person.age);
}
這樣經(jīng)過filter處理后得到的結(jié)果類型為FullPerson[],到達(dá)map對(duì)FullPerson類型的數(shù)據(jù)取值age就能得到我們想要的number類型數(shù)據(jù)了。
這里的type FullPerson = Required<Person>是typescript提供的一種全局通用方法,
-
Partial<Type>將類型屬性都設(shè)置為可選, - 文中提到的
Required<Type>,和Partial 相反,將類型屬性都設(shè)置為必須 -
readonly<Type>, 將類型屬性設(shè)置成Readonly
等等