Microsoft/TypeScript

Functions with fewer parameters NOT assignable to functions with more parameters defined as tuples union

Open

#56.766 geöffnet am 13. Dez. 2023

Auf GitHub ansehen
 (2 Kommentare) (2 Reaktionen) (0 zugewiesene Personen)TypeScript (6.726 Forks)batch import
BugDomain: check: Variance RelationshipsHelp Wanted

Repository-Metriken

Stars
 (48.455 Stars)
PR-Merge-Metriken
 (Durchschn. Merge 6T 17h) (9 gemergte PRs in 30 T)

Beschreibung

🔎 Search Terms

"tuple union" "tuple spread"

🕗 Version & Regression Information

This is the behavior in every version I tried, and I reviewed the FAQ for entries about

⏯ Playground Link

Playground Link

💻 Code

type Numbers = [a: number, b: number];
type Strings = [a: string, b: string];

type TupleArgs = (...args: Numbers) => void;
const f1: TupleArgs = (a) => console.log(a); // 👌

type SignatureOverload = { (...args: Numbers): void; (...args: Strings): void; }
type FnsIntersection = ((...args: Numbers) => void) & ((...args: Strings) => void);
type TuplesUnionArgs = (...args: Numbers | Strings) => void;

const f2: SignatureOverload = (a) => console.log(a); // 👌
const f3: FnsIntersection = (a) => console.log(a); // 👌
const f4: TuplesUnionArgs = (a) => console.log(a); // ❌

/**
 * Type '(a: string | number) => void' is not assignable to type 'TuplesUnionArgs'.
 *   Types of parameters 'a' and 'args' are incompatible.
 *     Type 'Numbers | Strings' is not assignable to type '[a: string | number]'.
 *       Type 'Numbers' is not assignable to type '[a: string | number]'.
 *         Source has 2 element(s) but target allows only 1.(2322)
 */

🙁 Actual behavior

Type '(a: string | number) => void' is not assignable to type 'TuplesUnionArgs'.
  Types of parameters 'a' and 'args' are incompatible.
    Type 'Numbers | Strings' is not assignable to type '[a: string | number]'.
      Type 'Numbers' is not assignable to type '[a: string | number]'.
        Source has 2 element(s) but target allows only 1. (2322)

🙂 Expected behavior

(a: string | number) => void should be assignable to (...args: [a: number, b: number] | [a: string, b: string]) => void

Additional information about the issue

Since this issue has 2 pretty clean workarounds (signature overload, functions intersection), it is not critical. But it is an instance of inconsistent behaviour (which is annoying).

Contributor Guide