ウェブサイト検索

javascript - Typescript 4.4 のタプルユニオン推論の破壊


// Works fine in 4.3.5, not in 4.4.2

type ArgsTupleUnion<T> =
  | [obj: T, x: (arg: T) => void]
  | [y: (arg: number) => void];

function f<T>(...args: ArgsTupleUnion<T>) {}

f({ k: 15 }, (arg) => { // 4.3.5: arg is {k: number}, 4.4.2: arg is 'any'
  console.log(arg.k);
});

f((a: number) => {});


type ArgsTuple<T> =
  | [obj: T, x: (arg: T) => void]
  // | [y: (arg: number) => void];

function f2<T>(...args: ArgsTuple<T>) {}

f2({ k: 15 }, (arg) => { // Both 4.3.5 and 4.4.2: arg is {k: number}
  console.log(arg.k);
});

こちらがTS Playgroundのコードです。どの変更がこれを動作しなくさせたのかはわかりませんが、これが原因で4.4へのアップグレードができません。同じ問題に遭遇した方や、回避策のアイデアを持っている方はいませんか?

回答 #1

可能な回避策として、関数オーバーロードを使用することが考えられます

TypeScriptは、与えられた配列内の要素数を追跡するよりも、より具体的な型であるnumberを選択しているようです。

type ArgsTuple<T> = [obj: T, x: (arg: T) => void];
type NumArrFun = [y: (arg: number) => void];

type ArgsTupleUnion<T> =
  | ArgsTuple<T>
  | NumArrFun;

function f<T>(...args: ArgsTuple<T>): void
function f<T>(...args: NumArrFun): void
function f<T>(...args: ArgsTupleUnion<T>) {}

f({ k: 15 }, (arg) => { // 4.3.5: arg is {k: number}, 4.4.2: arg is 'any'
  console.log(arg.k);
});

f((a: number) => {});

遊び場リンク

関連記事