Skip to content

Unsound calls allowed on a function coming from a deferred indexed access when intersection is involvedΒ #54824

Open

Description

Bug Report

πŸ”Ž Search Terms

deferred index access unsound call union intersection

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

type A = {
  type: "A";
  value: string;
};

type B = {
  type: "B";
  value: number;
};

type Message = A | B;

export function handle<M extends Message>(callbacks: {
  [K in M["type"]]: (msg: (M & { type: K })["value"]) => unknown;
}) {
  window.addEventListener("message", (event) => {
    const msg = event.data as M;
    // should be an error because it's too permissive
    callbacks[msg.type as keyof typeof callbacks](msg.value);

    // one or the other must be wrong here
    callbacks[msg.type as keyof typeof callbacks]("");
    callbacks[msg.type as keyof typeof callbacks](100);
  });
}

πŸ™ Actual behavior

There is no error even though it should be based on Ander's comment here. Note that the comment is about a different variant of this signature, one using Extract. Both the Extract and intersection variants are essentially the same though - one errors today and one doesn't.

πŸ™‚ Expected behavior

I would expect to get an error here, just like in the Extract-based variant (TS playground)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Domain: Indexed Access TypesThe issue relates to accessing subtypes via index accessHelp WantedYou can do thisPossible ImprovementThe current behavior isn't wrong, but it's possible to see that it might be better in some cases

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions