Skip to content

tuple inference in array vs rest #34865

Closed
@jackmellis

Description

@jackmellis

TypeScript Version: typescript@3.8.0-dev.20191101

Search Terms: generic, tuple, rest

Code

const pipe = <A, B, C, D>(items: [ (a: A) => B, (b: B) => C, (c: C) => D ]): D => {
  return items.reduce((acc, fn) => fn(acc), {} as any) as D;
};

const result = pipe([
  // a: {}
  (a: {}) => ({
    ...a,
    age: 4,
  }),
  // b: { age: number }
  (b) => ({
    ...b,
    color: 'blue',
  }),
  // c: unknown
  (c) => ({
    ...c,
    height: 100,
  }),
]);

Expected behavior:
type is:

{ age: number, color: string, height: number }

Actual behavior:
Parameter c is unknown

In v3.3.x which I was working with (before testing against latest) c was inferred as {}, so the return type would be { height: 100 } (i.e. all other properties were dropped).

If you do the exact same code with a rest parameter instead of an array, it works absolutely fine:

const pipe2 = <A, B, C, D>(...items: [ (a: A) => B, (b: B) => C, (c: C) => D ]): D => {
  return items.reduce((acc, fn) => fn(acc), {} as any) as D;
};

Playground Link: https://codesandbox.io/embed/typescript-playground-export-kbre9

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions