type-challenge | 青训营笔记

126 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第15天

开始做type-challenges类型体操

Partial

接收一个类型,把传入类型的属性变为可选类型

interface Person {
  name: string
  age: number
  address?: string
}

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

type ResultType = MyPartial<Person>
type ResultType2 = Partial<Person>

Readonly

接收一个类型,把传入类型的属性变为readonly

interface Person {
  name: string
  age: number
  address?: string
}

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

type ResultType = MyReadonly<Person>
type ResultType2 = Readonly<Person>

Required

接收一个类型,把传入的类型变为必选

interface Person {
  name: string
  age: number
  address?: string
}

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

type ResultType = MyRequired<Person>
type ResultType2 = Required<Person>

Record

接收两个参,遍历传入的类型,返回对象类型, K 为对象的key的类型,T 为对象的value的类型

interface Person {
  name: string
  age: number
  address?: string
}

type res = keyof any

// 确保 K 是可以作为key的联合类型
type MyRecord<K extends keyof any, T> = {
  [P in K]: T
}

type ResultType = MyRecord<string, Person>
type ResultType2 = Record<string, Person>

Pick

接收两个参,从 T 中选取 K 属性的类型,组成一个新的类型

interface Person {
  name: string
  age: number
  address?: string
}

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

type ResultType = MyPick<Person, 'name' | 'age'>
type ResultType2 = Pick<Person, 'name' | 'age'>

Omit

和Pick相反,从 T 中过滤 K 属性的类型,组成一个新的类型

interface Person {
  name: string
  age: number
  address?: string
}

type MyOmit<T, K extends keyof T> = {
  [P in keyof T as P extends K ? never : P]: T[P]
}

type ResultType = MyOmit<Person, 'name' | 'age'>
type ResultType2 = Omit<Person, 'name' | 'age'>

Exclude

传入一个联合类型T,从 T 中过滤 K 属性的类型,组成一个新的类型

type Hobby = 'skiing' | 'swimming' | 'sing'

type MyExclude<T, K> = T extends K ? never : T

type ResultType = MyExclude<Hobby, 'sing'>
type ResultType2 = Exclude<Hobby, 'sing'>

Extract

传入一个联合类型T,从 T 中提取 K 属性的类型,组成一个新的类型

type Hobby = 'skiing' | 'swimming' | 'sing'

type MyExtract<T, K> = T extends K ? T : never

type ResultType = MyExtract<Hobby, 'sing'>
type ResultType2 = Extract<Hobby, 'sing'>

NonNullable

传入一个联合类型T,从 T 中过滤 null 和 undefined 属性的类型,组成一个新的类型

type Hobby = 'skiing' | 'swimming' | 'sing' | null | undefined

type MyNonNullable<T> = T extends null | undefined ? never : T
type MyNonNullable2<T> = T & {}

type ResultType = MyNonNullable<Hobby>
type ResultType2 = MyNonNullable2<Hobby>
type ResultType3 = NonNullable<Hobby>

这里特别说一下,自己实现的是第一版,然后点进去看源码发现是第二版的,不太懂这一版是什么原理, T & {},联合一个空对象,希望懂的佬说一下

ReturnType

传入一个函数类型,返回函数的返回值类型

type FunType = (a: string, b: string) => string

function foo() {
  return '123'
}

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

type ResultType = MyReturnType<FunType>
type ResultType2 = MyReturnType<typeof foo>
type ResultType3 = ReturnType<typeof foo>

目前就做了这十个常用