TypeScript中元组联合类型的类型收窄失效问题咨询
如何对联合元组类型进行类型收窄?
你遇到的问题是TypeScript默认没法通过检查元组单个元素来收窄整个联合元组类型,因为它无法自动关联元组内元素的类型依赖。不过有几种方法可以实现预期的类型收窄:
方法一:自定义元组类型守卫函数
直接写一个类型守卫,判断整个值是否属于目标元组类型:
declare const foo: [string, string] | [number, number]; declare function isNumber(x: unknown): x is number; function isNumberTuple(t: [string, string] | [number, number]): t is [number, number] { // 同时检查两个元素确保类型一致性 return isNumber(t[0]) && isNumber(t[1]); } if (isNumberTuple(foo)) { foo; // 此时类型已被收窄为 [number, number] }
方法二:解构后检查所有元素
把元组解构为单独变量,同时检查所有元素的类型,TypeScript会自动收窄原元组的类型:
declare const foo: [string, string] | [number, number]; declare function isNumber(x: unknown): x is number; const [first, second] = foo; if (isNumber(first) && isNumber(second)) { foo; // 类型被收窄为 [number, number] }
方法三:类型断言(不推荐)
如果你能确保逻辑正确性,可以手动用类型断言强制收窄,但这种方式跳过了TypeScript的类型检查,存在风险:
declare const foo: [string, string] | [number, number]; declare function isNumber(x: unknown): x is number; if (isNumber(foo[0])) { const narrowedFoo = foo as [number, number]; narrowedFoo; // 类型为 [number, number] }
为什么原代码无法收窄?
TypeScript的控制流分析目前无法自动识别联合元组中元素的绑定关系——只知道foo[0]是number,但没法推断foo[1]也必然是number,因为联合类型的元组是作为整体存在的,不是两个独立元素类型的组合。
内容的提问来源于stack exchange,提问作者Anon A. Mouse
相关产品推荐
相关产品推荐

