先说一下类型推断中的遍历,看一个题

对象部分属性只读

实现一个泛型MyReadonly2<T, K>,它带有两种类型的参数TK

类型 K 指定 T 中要被设置为只读 (readonly) 的属性。如果未提供K,则应使所有属性都变为只读,就像普通的Readonly<T>一样。

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

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

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

给出答案

type MyReadonly2<T, K extends keyof T = keyof T> = Omit<T, K> & { readonly [key in K]: T[key] };

在TS类型推断中,想进行遍历操作只能通过 元素 in 联合类型 ( key in unionKeys) 的方式进行操作,这就是本文的第一个内容,union 遍历。

再说第二部分,获取union,获取union一共有3种方式,见总结部分的2.1, 2.2, 2.3
其中2.3 分配条件类型有点晦涩,给出例子各位看官自己感受一下

type A1 = 'x' extends 'x' ? string : number; // string
type A2 = 'x' | 'y' extends 'x' ? string : number; // number

type P<T> = T extends 'x' ? string : number;
type A3 = P<'x' | 'y'> // ?

// 答案:
type A3 = P<'x' | 'y'>  // A3的类型是 string | number

总结:

  1. 类型推断中遍历操作通过 key in union 进行
  2. 想要获取union 可以通过 2.1 | 2.2 | 2.3三种方式得到
    2.1 对象的keyof; 如 T 是 Record<string, any>, keyof T 得到union
    2.2 数组[number]; 如T 是 string[], T[number] 得到union
    2.3 distributive (分配条件类型) T 是 union, T extends ? firstCase : secondCase得到union

同步更新到自己的语雀
https://www.yuque.com/dirackeeko/blog/wv3py9wpr11c9pfb


DiracKeeko
125 声望2 粉丝