statelyai / xstate

Actor-based state management & orchestration for complex app logic.
https://stately.ai/docs
MIT License
26.98k stars 1.24k forks source link

Bug: typegen.ts ist incomplete when moving state node configs to separate files #4849

Closed VILLAN3LL3 closed 5 months ago

VILLAN3LL3 commented 5 months ago

XState version

XState version 4

Description

As my state machine definition is growing, I decided to move substates into separate objects in separate files.

It's now looking like this:

const myMachine = createMachine({
 ...
 intial: "Initial",
 states: {
  initial: {
  ...
  always: [{ target: '.substate' }],
  states: {
   substate: { ...SUB_STATE },
  }
 }
}

In separate files:

export const SUB_STATE: StateNodeConfig<MyContext, any, MyEvent, BaseActionObject> = {
 type: "parallel",
 states: {
  subsubstate1: { ...SUB_SUB_STATE_1 },
  subsubstate2: { ...SUB_SUB_STATE_2 }
 }
}

SUB_SUB_STATE_1 and SUB_SUB_STATE_2 are also of type StateNodeConfig. It's working fine, but the TypeScript typegen doesn't recognize the sub-states which results in errors referencing a substate in a react component. The matchesStates property of the typegen.ts File looks like this: matchesStates: "initial" | "initial.substate" | { "initial"?: "substate"; };

state.matches("initial.substate.subsubstate1.xyz") will result in the error "No Overload Matches This Call".

Expected result

the typegen.ts file should include all states which are configured within createMachine

Actual result

The matchesStates property of the typegen.ts file is incomplete and looks like this: matchesStates: "initial" | "initial.substate" | { "initial"?: "substate"; };

state.matches("initial.substate.subsubstate1.xyz") will result in the error "No Overload Matches This Call".

Reproduction

https://stackblitz.com/edit/vitejs-vite-jmrvnd?file=src%2Fstate-machine.tsx

Additional context

No response

davidkpiano commented 5 months ago

Three small issues:

  // const matchesSubstate = current.matches('initial.substate.subsubstate1');
  const matchesSubstate = current.matches({
    initial: {
      substate: 'substate1',
    },
  });

Here is a working example: https://stackblitz.com/edit/vitejs-vite-ngjvqn?file=src%2FApp.tsx

VILLAN3LL3 commented 5 months ago

Thanks for your response. Yes I know that typegen is not yet ready for v5. That's why I use v4, see stackblitz example. @davidkpiano

davidkpiano commented 5 months ago

Thanks for the clarification (the original issue stated XState v5).

The last 2 points still stand: