【发布时间】:2019-02-28 10:59:39
【问题描述】:
我有一堆带有一个公共字段的接口,用作不相交联合的鉴别器。该字段由其他地方使用的几个枚举组成,因此我无法以合理的方式使其成为单个枚举。像这样(简化):
const enum Enum1 { key1 = 'key1', key2 = 'key2' }
const enum Enum2 { key1 = 'key1', key3 = 'key3' }
interface Item1 { key: Enum1; value: string; }
interface Item2 { key: Enum2; value: number; }
type Union = Item1 | Item2;
类型是这样使用的:
let item: Union = getUnionValue();
switch (item.key) {
case Enum1.key1:
// do something knowing the 'item.value' is 'string'
break;
// some other cases
case Enum2.key1:
// do something knowing the 'item.value' is 'number'
break;
// some more cases
}
当然,当不同枚举中的键等价时,这会导致运行时的损坏。
有没有办法检查鉴别器类型Union['key']实际上是否不相交,即是否所有使用的类型都不相交?换句话说,我正在寻找在上述类型上会出错的代码,表明Enum1.key1 与Enum2.key1 发生冲突。
我尝试了以下方法:
type Checker<T> = T extends any ?
(Exclude<Union, T>['key'] extends Extract<Union, T>['key'] ? never : any)
: never;
const test: Checker<Union> = null;
希望利用条件类型的分布,但这似乎不起作用。
【问题讨论】:
-
只是好奇为什么此时需要检查这个?
key1会缩小到value: string | object还不够吗? -
在问题本身中回答(包括示例用法)。