打字稿在元组联合中缩小范围
Posted
技术标签:
【中文标题】打字稿在元组联合中缩小范围【英文标题】:Typescript narrowing down within union of tuples 【发布时间】:2021-06-22 17:03:49 【问题描述】:假设我有这样的功能:
function foo(n: number): [number, undefined] | [undefined, number]
if (n % 2 === 0)
return [n, undefined];
return [undefined, n];
然后像这样调用这个函数:
function bar()
const [a, b] = foo(2);
if (a === undefined)
return b; // TypeScript infers b as number | undefined
return a; // TypeScript infers a as number (good!)
由于函数 foo 返回元组 (number, undefined)
或 (undefined, number)
,在没有通过 a === undefined
检查后,TypeScript 能够在返回时推断 a
的类型是数字。
在if
块内,因为a
未定义,我们(人类)可以将此处的foo 的返回类型推断为[undefined, number]
,因此b
的类型为数字。然而,TypeScript 似乎不够聪明,无法分辨这一点,并报告说它是number | undefined
。
是否有缩小元组联合范围的解决方法?
【问题讨论】:
在 Typescript 3.9.7 上按原样编译。这可能是在较新的 TS 版本中修复的问题吗? 对不起,不够清晰。它编译得很好,但我想要的是 bar 函数的返回类型是数字(因为理论上它应该是),但它被推断为数字 |未定义。 @SilvioMayolo 您是否启用了 strictNullChecks?这对我来说会引发编译器错误。 啊,这样就行了。好点子。我现在可以复制了。 【参考方案1】:TypeScript 的区分联合不会跟踪a
和b
之间的依赖关系,因此在您解构数组后,缩小a
不会影响b
的类型。要仍然实现所需的缩小,您可以直接测试数组元素,如下所示:
function bar()
const arr = foo(2);
if (arr[0] === undefined)
const b = arr[1]
return b; // TypeScript infers b as number (good!)
const a = arr[0]
return a; // TypeScript infers a as number (good!)
TypeScript playground
【讨论】:
【参考方案2】:截至版本。 4.6,TypeScript 现在处理 Destructured Discriminated Unions 并且您的代码 sn-p 将不再出错。
TypeScript playground
function bar()
const [a, b] = foo(2);
if (a === undefined)
return b; // TypeScript infers b as number (good!)
return a; // TypeScript infers a as number (good!)
TypeScript 4.6 RC - [link]
【讨论】:
以上是关于打字稿在元组联合中缩小范围的主要内容,如果未能解决你的问题,请参考以下文章