Typescript中的自定義守衛(wèi)和VUE3源碼中的范例

在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中我們,我們判斷類型,可以用:

  1. 類型判斷:typeof
  2. 實(shí)例判斷:instanceof
  3. 屬性判斷:in
  4. 字面量相等判斷:==, ===, !=, !==

舉個(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提供的一種全局通用方法,

  1. Partial<Type>將類型屬性都設(shè)置為可選,
  2. 文中提到的 Required<Type>,和Partial 相反,將類型屬性都設(shè)置為必須
  3. readonly<Type>, 將類型屬性設(shè)置成Readonly
    等等
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容