与Typescript中可能的类型文字进行匹配
以下面的例子为例:与Typescript中可能的类型文字进行匹配,typescript,pattern-matching,Typescript,Pattern Matching,以下面的例子为例: 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 } 以及以下“
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 }
以及以下“模式匹配”:
我并不特别喜欢这样,为了让案例理解op是UnaryOp
还是BinaryOp
,我必须列举所有的可能性。有没有一个紧凑的(er)方法来实现这一点
注意。考虑到这是一个简化的示例,可能还有其他类型的
Op
。我不认为有任何类型脚本技巧可以用来避免枚举所有的大小写
标签,因为标签必须是值,而不是类型
但是,可以使用if
语句而不是开关
,并且可以在if
表达式中使用
用户定义的类型保护是一个返回类型为类型谓词的函数。例如,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
}
这是一个极小的例子
default
在这种特殊情况下可以工作,但它在语义上并不等价。放弃switch
语句而使用调用的if
和else if
语句将是解决问题的一种方法。@cartant事实上,我就是这样解决的,谢谢:)想回答这个问题以便我能接受吗?事实上,我们可以将isSomething
助手推广到导出函数is(op:U,collection:Array):op是T{return collection.includes(op as T)}
@hugoseronenoreferreira我是否可以建议一种方法来确保并集和数组保持同步
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
}