TypeScript 的类型减法
在使用 TypeScript 开发的过程中,我们有时会遇到需要做类型减法的情况,例如 react-i18next
的 translate
方法会为组件的 Props 添加 i18n
等属性,而这个属性在通过 translate
生成的高阶组件的 Props 中是不应体现的。这时我们就需要用到类型减法。
具体实现:
// Diff / Omit taken from https://github.com/Microsoft/TypeScript/issues/12215#issuecomment-311923766
type Diff<T extends string, U extends string> = ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T];
type Omit<T, K extends keyof T> = Pick<T, Diff<keyof T, K>>;
interface A {
a: string;
b?: string;
c: number;
}
type B = Omit<A, 'c'>;
const a: A = {
a: '5',
c: 5,
};
const b: B = {
a: '5',
};
// Note: typeof B is (correctly) Pick<A, 'a' | 'b'>
这里主要用到了 Pick 工具类,Pick
可以从一个类型中取出一组属性生成新的类型。
TypeScript 2.8 更新
在 TypeScript 2.8 中,新增了条件类型 Exclude<T, U>
,它可以从T中排除那些可分配给U的类型。
所以上面的 Omit<T, K>
类型可以改写为 Pick<T, Exclude<keyof T, K>>
。