Vue学习笔记typescript

Typescript中的自定义守卫和VUE3源码中的范例

2022-03-28  本文已影响0人  fred_33c7

在Vue3 关于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就是自定义守卫,一般在ts中我们,我们判断类型,可以用:

  1. 类型判断:typeof
  2. 实例判断:instanceof
  3. 属性判断:in
  4. 字面量相等判断:==, ===, !=, !==

举个例子:

type Person = {
  name: string
  age?: number
}

// 获得所有age属性
function getPersonAges(persons: Person[]): number[] {
  return persons.filter(person => person.age !== undefined).map(person => person.age)
}

但是上面的代码会报错:

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'.

因为Person[]数组还是接收了Person类型,我们看filter()源码,会发现这样一个重载函数

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);
}

这样经过filter处理后得到的结果类型为FullPerson[],到达map对FullPerson类型的数据取值age就能得到我们想要的number类型数据了。


这里的type FullPerson = Required<Person>是typescript提供的一种全局通用方法,

  1. Partial<Type>将类型属性都设置为可选,
  2. 文中提到的 Required<Type>,和Partial 相反,将类型属性都设置为必须
  3. readonly<Type>, 将类型属性设置成Readonly
    等等
上一篇下一篇

猜你喜欢

热点阅读