Ts高级技巧总结

2023-11-18  本文已影响0人  指尖轻敲

keyof

类似于Object.keys(),用于把interface的所有key以“或”的形式组成一个新的类型,类似于枚举类型

interface Point {
    x: number;
    y: number;
}
type PointKeys = keyof Point
const key: PointKeys = 'x' // key只能赋值'x'或者'y'

实例:实现一个get函数来获取object的属性值

function get<T extends Record<string, unknown>, K extends keyof T>(obj: T, key: K): T[K]{
    return obj[key]
}
// 提示:使用Record<string, unknow>代替object

Record

上面用到了Record,那么就先来看它吧,通常用在声明对象时进行类型指定,第一个参数是key的类型,第二个参数是值得类型。

const obj: Record<string, string> = {
    name: 'lisa'
}

Record实现:这里又用到了keyof

type Record<K extends keyof any, T> = {
    [P in K]: T
}

in

Record的实现中用到了in,in是与keyof相对应的,keyof是产生枚举类型,通过in可以遍历枚举类型

type Keys = 'a' | 'x' | 'y'
type Obj = {
    [k in Keys]: unknow
}
==相当于==> {a: unknow, x: unknow, y: unknow}

实例:提前看一下Partial源码

type Partial<T> = {
    [K in keyof T]?: T[K] 
}
const obj: Partial<Point> = {
    x: 1,
    y: 1
}
// 因为obj类型相当于{x?: number, y?: number}

Partial / Required / Readonly

说到Partial,从源码可以看出Partial用来将类型的所有属性变为可选属性。
与其对应的还有Required(将所有属性变成必选)

type Required<T> = {
    [K in keyof T]: T[K]
}

Readonly比较简单,就是把所有属性变成只读属性

type C = {
  x?: string
  y: string
  z: string
}
type aa = Readonly<C>
// 以上相当于:
type aa = {  
    readonly x?: string;  
    readonly y: string;  
    readonly z: string;  
}

实现:

type Readonly<T> = {
    readonly[K in keyof T]: T[K]
}

Pick / Omit

Pick:从接口中挑拣选择部分属性作为新的类型,第一个参数:原接口类型,第二个参数:要选择的属性

type obj = {
    a: number,
    b: number,
    x: number
}
const aa: Pick<obj, 'a'> = {
    a: 1, // 只能有a属性
}

实现:

type Pick<T, K extends keyof T> = {
    [P in K]: T[K]
}

Omit的作用是从接口中,忽略排除部分属性作为新的类型。这里使用到了Exclude。如下:变量aa使用Omit声明类型,结果为obj中除了'a'和'x',剩下属性=>{b: number}

type obj = {
    a: number,
    b: number,
    x: number
}
const aa: Omit<obj, 'a' | 'x'> = {
    b: 1,
}

实现:

type Omit<T, K> = Pick<T, Exclude<keyof T, K>>

Exclude / Extract

Exclude字面意思就是“排除”,从第一个参数类型中排除第二个参数中有的类型。

type A = 'x' | 'y'
type B = 'x' | 'y' | 'z'
type Oo = Exclude<B, A>
const str: Oo = 'z' // B的z类型在A中没有,所以Exclude<B, A>就相当于'z'
// const str: Oo = 'x' // 不可以赋值

实现:

type Exclude<T, U> = T extends U ? never  T

Extract和Exclude相对应,用于取交集,即两者都有的类型

type Ex = Extract<'id'|'name'|'age', 'id'|'ho'>
const obj: Ex = 'id'
const obj: Ex = 'ho' //报错

实现:

type Exclude<T, U> = T extends U ? T : never

NonNullable

把联合类型中的null和undefined去掉之后的新类型

type Test = number | null | undefined
type Non = NonNullable<Test> // 等价于 type Non = number

实现:

type NonNullable<T> = T extends null | undefined ? never  T

is类型保护

使用is可以做类型的保护,常见实例如,isXXX函数,判定一个变量是不是指定类型。

function isStr(val: unknown): val is string {
    return typeof val === 'string'
}
function fn(value: unknown){
    if(isStr(value)){
        console.log(value.length) // 这里value已经判定为string类型,所有不会报错
    }
}
fn(12)

如果不使用is,直接使用boolean

function isStr(val: unknown): boolean {
    return typeof val === 'string'
}
function fn(value: unknown){
    if(isStr(value)){
        console.log(value.length) // 这里会报错,因为value可能是unknow类型
    }
}
上一篇 下一篇

猜你喜欢

热点阅读