Skip to content

Remapping a tuple constraint fails to provide a contextual type for the tuple elementsΒ #52650

@Andarist

Description

@Andarist

Bug Report

πŸ”Ž Search Terms

tuple constraint infer type parameter remapped reverse mapped contextual type

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

type Tuple<T> = readonly [T, ...T[]];

declare function bindAll<
  TTarget extends EventTarget,
  TTypes extends Tuple<keyof TTarget & `on${any}`>
>(
  target: TTarget,
  bindings: {
    [K in keyof TTypes]: {
      type: TTypes[K];
      listener: (
        ev: Parameters<Extract<TTarget[TTypes[K]], (...args: any[]) => any>>[0]
      ) => void;
    };
  }
): void;

bindAll({} as HTMLButtonElement, [
  {
    type: "onclick",
    listener: (event) => {
      event
      // ^? actual: string | Event | MouseEvent | ..., expected: MouseEvent
    },
  },
  {
    type: "onkeydown",
    listener: (event) => {
      event
      // ^? actual: string | Event | MouseEvent | ..., expected: KeyboardEvent
    },
  },
]);

πŸ™ Actual behavior

It should be possible to provide per element types using reverse mapped types when mapping over a type parameter with a tuple constraint. It works OK when at the argument position we use [...{ [K in keyof TTypes]: { /*...*/ } }] instead of { [K in keyof TTypes]: { /*...*/ } }. That is a weird workaround though.

πŸ™‚ Expected behavior

I would expect the contextual types to be correctly provided for each element separately, just like in the case of [...{ [K in keyof TTypes]: { /*...*/ } }] (TS playground)

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptHelp WantedYou can do this

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions