Variadic element of tuple-like intersection types are spreading incorrectly
See original GitHub issueTypeScript Version: 4.0.3
Search Terms: variadic tuple, variadic element, intersection type, tuple-like type
Code
type T1 = [...unknown[] & []]; // never[]
type T2 = [...number[] & [1, 2, 3]]; // (3 | 1 | 2)[]
Expected behavior: for T1
, I expected it to be []
(empty tuple type) and for T2
, I expected it to be [1, 2, 3]
.
Actual behavior: Both T1
and T2
became Array rather than tuple somehow. (T1
is deduced to never[]
, T2
is deduced to (3 | 1 | 2)[]
)
detailed explanation
In some perspective, unknown
could be recognized as type of all types. Therefore, [unknown]
is type of all type-level 1-tuples and intuitively, unknown[]
is type of all type-level n-tuples.
So [] <: unknown[]
is true (i.e. all empty type-level tuple is subtype of all type-level n-tuples) and you can check it simply with this code:
type M = [] & unknown[] extends [] ? [] extends [] & unknown[] ? true : false : false; // true
However, in spite of the fact that []
is subtype of unknown[]
therefore [] & unknown[]
is actually []
, variadic element of [] & unknown[]
somehow spreads as never[]
, which is incorrect and unintuitive.
Playground Link: Playground
Issue Analytics
- State:
- Created 3 years ago
- Reactions:7
- Comments:6 (2 by maintainers)
Top GitHub Comments
I was building type-level programming library since TS 4.1 finally added recursive conditional type alias. But after few hours, I encountered this issue and talked with others in twitter for a few days. That 👍seems to be added by people I know or discussed with me about this.
Unintuitive, yes; not as good as we could do, yes; but “incorrect” is somewhat debatable. (As an aside, this issue led to a great conversation about whether
never[]
is conceptually the same as[]
, despite specific differences in their assignability.) At any rate, sincenever[]
is not assignable to[]
, that’s a good argument forT1
being “incorrect,” but(3 | 1 | 2)[]
is clearly a valid representation of[1, 2, 3]
; it’s just not a very good one 😄Out of curiosity, since there are 4 👍 on an issue that seems somewhat arcane, is this coming up in practice somewhere?