Skip to content

Inferences made when trying to match an overload are carried over to matching consecutive overloads #46312

Open
@Andarist

Description

@Andarist

Bug Report

🔎 Search Terms

overload inference generic consecutive subsequent following

the only issue that I have found that might be related to this is this one but I can't assess on my own if they are the same or not

🕗 Version & Regression Information

This is the behavior present in all 4.x versions available on the playground, including 4.5-beta.

⏯ Playground Link

Playground link with relevant code

💻 Code

interface TypegenDisabled {
  "@@xstate/typegen": false;
}
interface TypegenEnabled {
  "@@xstate/typegen": true;
}
interface EventObject {
  type: string;
}
interface ActionObject<TEvent extends EventObject> {
  _TE: TEvent;
}

interface StateMachine<
  TEvent extends EventObject,
  TTypesMeta = TypegenDisabled
> {
  _TE: TEvent;
  _TRTM: TTypesMeta;
}

interface MachineOptions<TEvent extends EventObject> {
  action?: ActionObject<TEvent>;
}

type MaybeTypegenMachineOptions<
  TEvent extends EventObject,
  TTypesMeta = TypegenDisabled
> = TTypesMeta extends TypegenEnabled
  ? {
      action?: ActionObject<{ type: "WITH_TYPEGEN" }>;
    }
  : MachineOptions<TEvent>;

declare function assign<TEvent extends EventObject>(
  assignment: (ev: TEvent) => void
): ActionObject<TEvent>;

// atm I have a single signature and it **matches**
// however, if I uncomment this additional overload then **no signature** matches
// if later on I reorder the signatures then the first one (the one that is currently not commented out) matches

// what happens here is that some inferences made when attempting to match the first overload are cached 
// and "carried over" to matching the second overload - which makes the whole thing fail

// declare function useMachine<
//   TEvent extends EventObject,
//   TTypesMeta extends TypegenEnabled
// >(
//   getMachine: StateMachine<TEvent, TTypesMeta>,
//   options: MaybeTypegenMachineOptions<TEvent, TTypesMeta>
// ): { first: true };
declare function useMachine<TEvent extends EventObject>(
  getMachine: StateMachine<TEvent>,
  options?: MachineOptions<TEvent>
): { second: true };

const machine = {} as StateMachine<{ type: "WITHOUT_TYPEGEN" }>;

const ret = useMachine(machine, {
  action: assign((_ev) => {
    ((_type: "WITHOUT_TYPEGEN") => null)(_ev.type);
  }),
});

🙁 Actual behavior

No overload signature matches

🙂 Expected behavior

I would expect a signature to match when it's used as one of the overloads if it matches on its own. And I would expect for inferences made in a failed attempt to match a signature to have no effect on matching the following signatures.

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptNeeds InvestigationThis issue needs a team member to investigate its status.RescheduledThis issue was previously scheduled to an earlier milestone

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions