generated at
generic関数宣言内のVariadic Tuple Types

関数宣言の引数部分で[...XS]と書いた時の意味
XS を、配列型ではなく、TypeScriptのTuple型として推論して欲しいときに使う


前提条件
genericな関数に型をつけるときに使える
型引数には、arrayかtupleの制約が入っている必要がある
XS extends unknown[]
XS extends readonly unknown[]
例.ts
declare function hoge<XS extends unknown[]>( values: readonly [...XS] ): ...


どう変わるのか
上の前提条件を満たしているときに、 [...XS] と書くと、
XS が、配列型ではなく、Tuple型として推論される
XS [...XS] で意味が変わるの難しすぎない?mrsekut



意味が変わっている例
この記事と同じ関数の定義を使う
普通にただの XS と書いた時、
ts
const fn = <XS extends readonly unknown[]>(arr: XS): XS => arr const hoge = fn(['foo', 1]); // (string|number)[]
返り値は、 ['foo',1] だが、 (string|number)[] と推論される
[...XS] と書いた時
ts
const fn = <XS extends readonly unknown[]>(arr: [...XS]): XS => arr; const t = fn(['foo', 1]); // [string,number]
返り値は、 [string,number] と推論される





実際に使っている例







tupleに対するindex accessに対する推論
ちょっとだけ中心機能とズレている話だけど、これもすごいなmrsekut
ts
function head<T extends readonly any[]>(args: readonly [...T]) { const result = args[0]; return result; } const str = head(["foo", "bar"] as const); // "foo"
tupleでないと、効能は薄れるが、
ts
function head<T extends readonly any[]>(args: [...T]) { const result = args[0]; return result; } const str = head(["foo", "bar"]); // string const num = head([1, "bar"]); // number
tupleじゃないと、 [1, 'bar'] なんてリストは作らないので、結局tuple使う時に嬉しい、という話だなmrsekut


参考