首先来看这样一个 ts 例子

import { Button, ButtonProps } from './components/button'

type Omit<T, K> = Pick<T, Exclude<keyof T, K>>
type BigButtonProps = Omit<ButtonProps, 'size'>

function BigButton(props: BigButtonProps) {
  return Button({ ...props, size: 'big' })
}
复制代码

如果对这个例子很清晰,大佬请点击右上角。

如果不清楚 我们可以来往下共同探索一番。。

partial, Readonly, Record, Pick

partial

Partial 作用是将传入的属性变为可选项.

keyof, in

首先我们需要理解两个关键字 keyof 和 in, keyof 可以用来取得一个对象接口的所有 key 值.比如

interface Foo {
  name: string;
  age: number
}

// T -> "name" | "age"
type T = keyof Foo

type Keys = "a" | "b"
type Obj =  {
  [p in Keys]: any
}
// Obj -> { a: any, b: any }
复制代码

keyof 产生联合类型, in 则可以遍历枚举类型, 所以他们经常一起使用, 看下 Partial 源码

type Partial<T> = { [P in keyof T]?: T[P] };
复制代码

使用

interface Foo {
  name: string;
  age: number;
}

type B = Partial<Foo>;

// 最多只能够定义 name, age 中的属性(可以不定义)
let b: B = {
  name: '1',
  age: 3,
};
复制代码

Required

Required 的作用是将传入的属性变为必选项, 源码如下

type Required<T> = { [P in keyof T]-?: T[P] };
复制代码

我们发现一个有意思的用法 -?, 这里很好理解就是将可选项代表的 ? 去掉, 从而让这个类型变成必选项. 与之对应的还有个+? , 这个含义自然与-?之前相反, 它是用来把属性变成可选项的.

Pick