采用以下最小例子:
type BinaryOp = 'MOV'
type UnaryOp = 'ADD' | 'SUB' | 'JRO'
const BinaryOps: BinaryOp[] = ['MOV']
const UnaryOps: UnaryOp[] = ['ADD', 'SUB', 'JRO']
type Line =
{ op: BinaryOp, a: number, b: number }
| { op: UnaryOp, a: number }
以下“模式匹配”:
switch (line.op) {
case 'ADD':
case 'SUB':
case 'JRO':
return `${line.op} ${line.a}`
case 'MOV':
return `${line.op} ${line.a}, ${line.b}`
}
我不是特别喜欢这样,为了让案例理解op是UnaryOp
或BinaryOp
,我必须列举所有可能性。有没有紧凑的(呃)方法来实现这个目标?
注意。请注意,这是一个简化的示例,可能还有其他类型的Op
。
答案 0 :(得分:2)
我不相信可以使用任何TypeScript技巧来避免必须枚举所有case
标签,因为标签必须是值 - 而不是类型。
但是,您可以使用if
语句而不是switch
语句,并且可以在if
表达式中使用user-defined type guards。
用户定义的类型保护是一种函数,其返回类型是类型谓词。例如,UnaryOp
的用户定义类型保护可能如下所示:
function isUnaryOp(op: string): op is UnaryOp {
return op && UnaryOps.includes(op as any);
}
在if
语句中使用时,用户定义的类型保护会缩小类型:
if (isUnaryOp(line.op)) {
const op = line.op; // Inferred to be UnaryOp
} else if (isBinaryOp(line.op)) {
const op = line.op; // Inferred to be BinaryOp
} else {
const op = line.op; // Inferred to be never
}