**类型脚本版本:**4.0.3
**检索词:**可变元组、可变元素、交集类型、类元组类型
代码
type T1 = [...unknown[] & []]; // never[]
type T2 = [...number[] & [1, 2, 3]]; // (3 | 1 | 2)[]
**预期行为:**对于T1
,我预期它是[]
(空元组类型),对于T2
,我预期它是[1, 2, 3]
。
实际行为:T1
与T2
不知何故都变成了Array而不是Tuple.(T1
被推导为never[]
,T2
被推导为(3 | 1 | 2)[]
)
详细解释
因此,[unknown]
是 * 所有类型级1元组的类型 *,并且直观地,unknown[]
是 * 所有类型级n元组的类型 。
因此[] <: unknown[]
为真(即, 所有空类型级元组 * 是 * 所有类型级n元组 * 的子类型),您可以使用以下代码简单地检查它:
type M = [] & unknown[] extends [] ? [] extends [] & unknown[] ? true : false : false; // true
然而,尽管[]
是unknown[]
的子类型,因此[] & unknown[]
实际上是[]
,但[] & unknown[]
的变元不知何故传播为never[]
,这是不正确的和不直观的。
**Playground链接:**Playground
6条答案
按热度按时间7ajki6be1#
不正确和不直观
不直观,是的;没有我们能做得那么好,是的;但“不正确”多少有些争议。(顺便说一句,这个问题引发了一场关于
never[]
在概念上是否与[]
相同的讨论,尽管它们在可赋值性上存在特定的差异。)无论如何,由于never[]
不能赋值给[]
,因此这是一个很好的论据,可以证明T1
是“不正确的,但是(3 | 1 | 2)[]
显然是[1, 2, 3]
的有效表示;只是不太好😄出于好奇,既然有4👍个关于一个似乎有些神秘的问题,这是在实践中出现的地方?
hsvhsicv2#
自从TS 4.1终于添加了递归条件类型别名之后,我一直在构建类型级编程库。但是几个小时后,我遇到了这个问题,并在twitter上和其他人聊了几天。这👍似乎是我认识的人添加的,或者和我讨论过这个问题。
ibps3vxo3#
我同意T1的说法是正确的,很抱歉用错了词。但是,我想我们都同意(3| 2个|1)此时[]不是一个正确或有用的类型,因为一些重要信息被丢弃,它可能会导致一些意外的问题。🙂
(抱歉格式松散,我用移动的写了这篇评论...)
sqyvllje4#
自从TS 4.1终于添加了递归条件类型别名之后,我一直在构建类型级编程库。但是几个小时后,我遇到了这个问题,并在twitter上和其他人聊了几天。这👍似乎是我认识的人添加的,或者和我讨论过这个问题。
我也有类似的情况。我试图Map嵌套的元组类型。
pqwbnv8z5#
这也会变成数组型别,即使交集的两边都是以Tuple开始:
qyyhg6bp6#
其实这也是坏的
[...[1] & [unknown]]
当我试图从用其他属性扩充的元组中获取元组时,也遇到了类似的“问题”。
通过调查,我发现即使是
[...([1,2,3] & unknown[])]
也是有损耗的。你会发现我在取回元组方面的不同尝试。显式地迭代数字键有效,但我很惊讶我不得不走这么远。