TypeScript 类型体操

资料

  1. TypeScript Playground
  2. Github类型体操地址

基础语法

1.0、keyof

有点 Object.keys 那意思,用作获取 interface 和对象类型的 “键”

interface Person {
  name: string;
  age: number;
  gender: 'male' | 'female';
}

 // 等同于 "name" | "age" | "gender"
type PersonKeys = keyof Person;

类型体操

第 01 题:实现 Pick

https://github.com/type-challenges/type-challenges/blob/main/questions/00004-easy-pick/README.zh-CN.md

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

// 1.MyPick 实现
type MyPick<T, K extends keyof T> = {
  [P in K]: T[P]
}

// 2.验证
type TodoPreview = MyPick<Todo, 'title' | 'completed'>

// 3.实现
const todo: TodoPreview = {
  title: 'Clean room',
  completed: false,
}

第 02 题:实现 Readonly

https://github.com/type-challenges/type-challenges/blob/main/questions/00007-easy-readonly/README.zh-CN.md

interface Todo {
  title: string
  description: string
}

// 1.MyReadonly 实现  
type MyReadonly<T> = {
  readonly [K in keyof T]:  T[K]
}

// 2.验证
const todo: MyReadonly<Todo> = {
  title: "Hey",
  description: "foobar"
}

// 3.使用
todo.title = "Hello" // Error: cannot reassign a readonly property
todo.description = "barFoo" // Error: cannot reassign a readonly property

第 03 题:实现 Readonly2

https://github.com/type-challenges/type-challenges/blob/main/questions/00008-medium-readonly-2/README.zh-CN.md

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

// 1.实现
type MyReadonly2<T, K extends keyof T = keyof T>={
  readonly [P in K]: T[P]
} & {
  [P in Exclude<keyof T, K>]: T[P]
}

// 2.验证
const todo: MyReadonly2<Todo, 'title' | 'description'> = {
  title: "Hey",
  description: "foobar",
  completed: false,
}

// 3.使用
todo.title = "Hello" // Error: cannot reassign a readonly property
todo.description = "barFoo" // Error: cannot reassign a readonly property
todo.completed = true // OK

第 04 题:实现 Tuple to Object

https://github.com/type-challenges/type-challenges/blob/main/questions/00011-easy-tuple-to-object/README.zh-CN.md

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

// 1.实现
type TupleToObject<T extends readonly any[]> = {
  [P in T[number]]: P
}

// 2.使用 和 验证
type result = TupleToObject<typeof tuple> // expected { 'tesla': 'tesla', 'model 3': 'model 3', 'model X': 'model X', 'model Y': 'model Y'}

第 05 题:实现 Exclude

https://github.com/type-challenges/type-challenges/blob/main/questions/00043-easy-exclude/README.zh-CN.md

// 1.实现
type MyExclude<T,U> = T extends  U ? never : T

// 2.使用 和 验证
type Result = MyExclude<'a' | 'b' | 'c', 'a'> // 'b' | 'c'

第 06 题:实现 Omit

https://github.com/type-challenges/type-challenges/blob/main/questions/00003-medium-omit/README.zh-CN.md

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

// 第1种实现方式
type MyOmit<T,K extends keyof T> = {
  [P in Exclude<keyof T, K>]: T[P]
}

// 第2种实现方式  这个不用 Exclude
type MyOmit1<T, K extends keyof T>={
  [P in keyof T as P extends K ? never:P]: T[P]
}

// 3.使用
type TodoPreview = MyOmit<Todo, 'description' | 'title'>

// 4.验证
const todo: TodoPreview = {
  completed: false,
}

第 07 题:实现 Get Return Type

题目地址:https://github.com/type-challenges/type-challenges/blob/main/questions/00002-medium-return-type/README.zh-CN.md

https://jkchao.github.io/typescript-book-chinese/project/compilationContext.html#typescript-编译

const fn = (v: boolean) => {
  if (v)
    return 1
  else
    return 2
}

// 1.实现
type MyReturnType<T extends Function> = T extends (...args: any) => infer R ? R: never;

// 2.使用 和 验证
type a = MyReturnType<typeof fn> // 应推导出 "1 | 2"

第 08 题:实现 Deep Readonly

https://github.com/type-challenges/type-challenges/blob/main/questions/00009-medium-deep-readonly/README.zh-CN.md

type X = { 
  x: { 
    a: 1
    b: 'hi',
  }
  y: 'hey'
}

type Expected = { 
  readonly x: { 
    readonly a: 1
    readonly b: 'hi'
  }
  readonly y: 'hey' 
}

// 1.实现
type DeepReadonly<T> = keyof T extends never
  ? T
  : { readonly [k in keyof T]: DeepReadonly<T[k]> };

// 2.使用 和 验证
type Todo = DeepReadonly<X> // should be same as `Expected`

第 09 题:实现 First of Array

https://github.com/type-challenges/type-challenges/blob/main/questions/00014-easy-first/README.zh-CN.md

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

// 1.实现
// type First<T extends any[]> = T extends []? never: T[0];
// type First<T extends any[]> = T["length"] extends 0 ? never: T[0] 
// type First<T extends any[]> = T[0]
type First<T extends any[]> = T extends [infer A, ...infer regs] ? A: never

// 2.使用 和 验证
type head1 = First<arr1> // 应推导出 'a'
type head2 = First<arr2> // 应推导出 3
type head3 = First<arr3> // 应推导出 undefined | never

第 10 题:实现 Push

https://github.com/type-challenges/type-challenges/blob/main/questions/03057-easy-push/README.zh-CN.md

// 1.实现
type Push<T extends unknown[],K> = [...T,K]

// 2.使用 和 验证
type Result = Push<[1, 2], '3'> // [1, 2, '3']

第 11 题:实现 Concat

https://github.com/type-challenges/type-challenges/blob/main/questions/00533-easy-concat/README.zh-CN.md

// 1.实现
type Concat<K extends unknown[],U extends unknown[]> = [...K,...U]

// 2.使用 和 验证
type Result = Concat<[1], [2]> // expected to be [1, 2]

第 12 题:实现 Includes

https://github.com/type-challenges/type-challenges/blob/main/questions/00898-easy-includes/README.zh-CN.md

// 1.实现
type Includes<T extends readonly any[], U>={
  [P in T[number]]: true
}[U] extends true ? true:false

// 2.使用 和 验证
type isPillarMen = Includes<['Kars', 'Esidisi', 'Wamuu', 'Santana'], 'Dio'> // expected to be `false`

第 13 题:实现 Unshift

https://github.com/type-challenges/type-challenges/blob/main/questions/03060-easy-unshift/README.zh-CN.md

// 1.实现
type Unshift<T extends any[],U>=[U,...T]

// 2.使用 和 验证
type Result = Unshift<[1, 2], 0> // [0, 1, 2,]

第 14 题:实现 Last of Array

https://github.com/type-challenges/type-challenges/blob/main/questions/00015-medium-last/README.zh-CN.md

type arr1 = ['a', 'b', 'c']
type arr2 = []

// 1.实现
type Last<T extends any[]> = T extends [...infer U, infer L] ? L :never;

// 2.非常骚的写法,思路真的太重要了
// type Last<T extends any[]> = [any, ...T][T["length"]];

// 3.使用 和 验证
type tail1 = Last<arr1> // 应推导出 'c'
type tail2 = Last<arr2> // 应推导出 1

第 15 题:实现 Pop

https://github.com/type-challenges/type-challenges/blob/main/questions/00016-medium-pop/README.zh-CN.md

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

// 1.实现
type Pop<T extends any[]> = T extends [...infer U, infer _] ? U : never

// 2.使用 和 验证
type re1 = Pop<arr1> // expected to be ['a', 'b', 'c']
type re2 = Pop<arr2> // expected to be [3, 2]

第 16 题:实现 AayOf

https://github.com/type-challenges/type-challenges/blob/main/questions/00949-medium-anyof/README.zh-CN.md

// 实现方案1
type AnyOf<T extends any[]> =  T[number] extends 0 | '' | false | [] | {[key: string]: never}
? false : true;


// 实现方案2
// type Falsy = 
//   | false
//   | 0
//   | ''
//   | []
//   | { [key: string]: never }

// type AnyOf<T extends readonly any[]> = 
//   T extends Falsy[] ? false : true

// 3.使用 和 验证
type Sample1 = AnyOf<[1, '', false, [], {}]> // expected to be true.
type Sample2 = AnyOf<[0, '', false, [], {}]> // expected to be false.

第 17 题:实现 Shift

https://github.com/type-challenges/type-challenges/blob/main/questions/03062-medium-shift/README.md

// 1.实现 并且使用 和 验证
type Shift<T extends any[]>= T extends [infer T, ...infer L] ? [...L]:never;
type Result = Shift<[3, 2, 1]> // [2, 1]

// // 2.骚操作 实现 并且使用 和 验证 
type Shift1<T extends any[]> = T extends [any,...infer U]?U:never 
type Result1 = Shift1<[3, 2, 1]> // [2, 1]

往期内容

点击链接查看:https://www.yuque.com/chuxin-cs/it/ge9wybczy0wsq1l1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值