我有一个操作枚举(不幸的是,我不能改变它):
enum OpType {
OpA = 0,
OpB = 1,
}
...以及一组用于携带每个操作所需数据的对象的类型:
type A = {
readonly opType: OpType.OpA;
readonly foo: number;
};
type B = {
readonly opType: OpType.OpB;
readonly bar: string;
};
......最后是确保每个操作都得到处理的处理程序函数:
type Ops = A | B;
export const ensureExhaustive = (_param: never) => {};
export const handleOp = (op: Ops) => {
switch (op.opType) {
case OpType.OpA:
if (op.foo < 80) { /* … */ }
break;
case OpType.OpB:
if (op.bar === 'foo') { /* … */ }
break;
default:
ensureExhaustive(op);
}
}
然而,这个handleOp
函数只能确保我们处理显式添加到Ops联合体的内容--与OpType
枚举的连接已经丢失,因此如果OpC = 2
被添加到enum
,将不会检测到这没有被处理。
如何将枚举值(可能通过Ops
类型)“连接”到handleOp
中的switch
语句,以确保处理每个值?
1条答案
按热度按时间3bygqnnd1#
您可以将
ensureExhaustive
函数重新创建为类型:然后你可以定义一个伪类型来确保某个类型是
never
:方便的是,存在一个实用程序
Exclude
,它已经具有我们想要的行为:换句话说,如果第二个参数包含第一个参数,则此类型的结果为
never
。转换到我们的用例,如果Ops["opType"]
使用OpType
的所有成员,则此类型的结果为never
。我们可以做的另一个技巧是使
ensureExhaustive
成为 generic,这样它就具有签名因此我们可以使用Python 4.7中引入的示例化表达式,而无需使用
EnsureExhaustive
类型:当然,如果您启用了
noUnusedLocals
或使用了linter,则此伪类型可能会导致错误或警告。