Here is the code:
declare function test1<T extends unknown[]>(value: T): T
const res1 = test1([1, 2, 3]) // type is number[]
declare function test2<T extends unknown[]>(value: [...T]): T
const res2 = test2([1, 2, 3]) // type is [number,number,number]
as you can see, if I use ... separator operator
, I got totally different result type, and I think [...T]
is same with T
,because T extends array.
is it a feature I should keep in mind and move on?
CodePudding user response:
It's a feature, be it not a very well-documented one. If you check this PR on Variadic tuple types, the section Spreads in array literals contains
The type
[...T]
, whereT
is an array-like type parameter, can conveniently be used to indicate a preference for inference of tuple types:
declare function ft1<T extends unknown[]>(t: T): T;
declare function ft2<T extends unknown[]>(t: T): readonly [...T];
declare function ft3<T extends unknown[]>(t: [...T]): T;
declare function ft4<T extends unknown[]>(t: [...T]): readonly [...T];
ft1(['hello', 42]); // (string | number)[]
ft2(['hello', 42]); // readonly (string | number)[]
ft3(['hello', 42]); // [string, number]
ft4(['hello', 42]); // readonly [string, number]
It allows you to pass an array as a tuple without having to add as const
(which makes the array and its elements read-only).