类型体操

153 阅读1分钟

内置类型体操

1.Pink

// 可以理解为 T = object
// keyof T 可以理解为 object的所有属性集合,所以 K extends keyof T,可以理解为K是object部分属性的集合
type MyPick <T extends object,K extends keyof T> = {
  //[ in ]代表循环遍历,一次遍历K中所有属性,然后在所有属性中进行匹配
  [Key in K] : T[Key]
}

interface Todo{
  title:string
  description:string
  completed:boolean
}

type TodoPreview = MyPick<Todo, 'title'|'completed'>

const todo:TodoPreview = {
  title:"Clean room",
  completed:false
}
  • K extends keyof T:表示K只能是keyof T的子类型,如果我们在使用Pick的时候传递了不存在于T的字段,会报错:

2.Readonly

type MyReadonly<T extends object>={
  readonly [key in keyof T] : T[key]
}

interface Todo2 {
  title:string
  description:string
}

const todo2 : MyReadonly<Todo2>={
  title:"Hey",
  description:"foobar"
}

// todo2.title = "Hello"
// todo2.description = "barFoo"

3.Exclude

type ExcludeResult = Exclude<'name'|'age'|'sex', 'sex'|'address'>
type MyExclude<T,U> = T extends U ? never:T
  • T extends U : 从 T 的子类型开始分发
T extends U 
=> 'name'|'age'|'sex' extends 'sex'|'address'
=> (
    'name' extends 'sex'|'address' ? never : 'name' |
    'age' extends 'sex'|'address' ? never : 'age'   |
    'sex' extends 'sex'|'address' ? never : 'sex'
)
=> 'name'|'age'

4.Parameters(函数的参数类型)

const add = (a:number,b:string):void=>{}
//[number,string]
type result = MyParameters<typeof add>

type MyParameters<T extends (...args:any[])=>any> = T extends (...args:infer R)=>any?R:never

5.Partial(所有属性可填)

type Person = {
    name:string;
    age?:number;
}
type PartialResult = MyPartial<Person>

type MyPartial<T>={
    [P in keyof T]?:T[P]
}

6.Required(所有属性必填)

type Person = {
    name:string;
    age?:number;
}
type RequiredResult = MyRequired<Person>

type MyRequired<T>={
    [P in keyof T]:T[P]
}

自定义泛型工具类型

7.元组转换为对象

confst tuple = ['tesla','model 3','model X','model Y'] as const

type result = TupleToObject<typeof tuple>

type TupleToObject<T extends readonly any[]> = {
    [K in T[number]] = K
}

// { 
    tesla: 'tesla', 
    'model 3': 'model 3', 
    'model X': 'model X', 
    'model Y': 'model Y'
   }

8.# 取出数组第一个元素

type arr1 = ['a','b','c']
type arr2 = [3,2,1]

type head1 = First<arr1> // expected to be 'a'
type head2 = First<arr2> // expected to be 3

type First<T extends any[]>=T['length'] extends 0?never:T[0]

9.获取元组长度

type tesla = ['tesla', 'model 3', 'model X', 'model Y']
type spaceX = ['FALCON 9', 'FALCON HEAVY', 'DRAGON', 'STARSHIP', 'HUMAN SPACEFLIGHT']

type teslaLength = Length<tesla> // expected 4
type spaceXLength = Length<spaceX> // expected 5

type Length<T extends readonly any[]> = T['length']