此代码:
type WithOr = {a:string} & ({b?:true, c?:never} | {b?:false, c:number})
type Ommited = Omit<WithOr, 'a'>
const m1: Ommited = {b: true};
const m2: WithOr = {...m1, a: 'a'}
最终将出现错误:
...
Type 'boolean | undefined' is not assignable to type 'false | undefined'.
...
似乎Omit抛弃了“或”逻辑。
还有其他方法可以使用Omit(在其中带有“或”符号)重用我的复杂类型吗?
答案 0 :(得分:1)
这与Omit
的工作方式有关。在lib.es5.d.ts
中定义的方式如下:
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
Exclude<keyof T, K>
生成所有键的并集,除了您作为K
传递的键之外。因此,在您的示例中为'b' | 'c'
。
Pick
然后使用映射类型迭代这些键并创建新的对象类型:
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
因此,该类型被“展平”。对于b
,T['b']
返回true | false | undefined
,TypeScript将其简化为boolean | undefined
。
结果是:
type Ommited = {
b?: boolean | undefined;
c?: number | undefined;
}
我认为您在这里可以做的最好的事情是将“或”部分提取到命名类型中,然后重复使用:
type OrPart = {b?:true, c?:never} | {b?:false, c:number}
type WithOr = {a:string} & OrPart
const m1: OrPart = {b: true};
const m2: WithOr = {...m1, a: 'a'}