TS进阶实战

ps:如果对TS的一些进阶使用不太熟悉可以先去看看

TS进阶使用

场景一

  • 从某个类型中选取某个属性生成新的类型

使用场景如下所示:我们需要从AuthStore 中推导出UserObj的类型

export class AuthStore {
    
    
    userObj = {
    
    
      name: 'zlz',
      age: 23,
      phone: '12345689'
    }

    setUserObj(obj: UserObj) {
    
    
        this.userObj = obj;
    }
}

根据以上使用场景需要实现一个工具函数——GetKeyType

  1. 第一步利用InstanceType推导出类的类型;

  2. 第二步写一个工具函数GetKeyType——从类的类型中获取userObj 的type

// 利用InstanceType推导出类的类型;
type UserObj = GetKeyType<InstanceType<typeof AuthStore>, 'userObj'>
// K 是 GetKeyType 传入的第二个参数 且是T的子属性
type GetKeyType<T,K extends keyof T> = T[K]
export class AuthStore {
    
    
    userObj = {
    
    
      name: 'zlz',
      age: 23,
      phone: '12345689'
    }

    setUserObj(obj: UserObj) {
    
    
        this.userObj = obj;
    }
}

推导出来的类型如下
// interface UserObj{
    
    
//   name: string
//   age: number
//   phone: string
// }

场景二

  • 想根据传入的key将这个key变为可选

使用场景如下所示:我们有一个产品信息的泛型,但是之前迭代没有intruduce(产品介绍)这个字段;我们要兼容老数据

interface Product {
    
    
  name: string
  id: string
  intruduce: string
  ...
}

实现方式一:

interface Product {
    
    
  name: string
  id: string
  intruduce: string
}

interface NewProduct extends Omit<Product, 'intruduce'> {
    
    
  intruduce?: string
}

实现方式二:

根据以上使用场景需要实现一个工具函数——SetPartial
ps:很明显方式二好些,工具函数可以复用,使用更加简便

type SetPartial<T,K extends keyof T> = Omit<T,K> & Partial<Pick<T, K>>

interface Product {
    
    
  name: string
  id: string
  intruduce: string
}

type NewProduct = SetPartial<Product, 'intruduce' | 'id'>

得到的NewProduct 
// interface NewProduct{
    
    
//   name: string
//   id?: string
//   intruduce?: string
// }

场景三

  • 将多维数组扁平化

使用场景如下所示:

[['a'], ['ee',['b', 'c']], ['d']]
转化为
type Result = "a" | "b" | "c" | "ee" | "d"

需要利用infer 和递归来实现一个工具类——NaiveFlat

type NaiveFlat<T extends any[]> = T extends (infer P)[] ? P extends any[] ? NaiveFlat<P> : P : never;

type Result = NaiveFlat<[['a'], ['ee',['b', 'c']], ['d']]>;

// type NaiveResult = "a" | "b" | "c" | "ee" | "d"

1.infer TS的关键字:预判类型推导

T extends (infer P)[]
P 它可以是strng | number | null | undefined 这些基础类型
注意:infer只能用于在extends的地方

2. NaiveFlat执行过程


 1.  T 是 [['a'], ['ee',['b', 'c']], ['d']] ,然后T extends (infer P)[] ? P extends any[] ?都为真,执行 NaiveFlat<P>;
 2.  NaiveFlat<P>中的P是数组T中的每一个子元素,接下来执行NaiveFlat<['a']>;
 3. T 是 ['a'],T extends (infer P)[]?为真,P extends any[]为假;
 4. 让后直接返回P(p就是‘a’)
 然后到2.重复执行...

猜你喜欢

转载自blog.csdn.net/weixin_44441196/article/details/127300158
ts
今日推荐