statelyai / xstate

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

Bug: Type issue with `not` helper #5090

Open flugg opened 2 months ago

flugg commented 2 months ago

XState version

XState version 5

Description

I'm trying to create a package that creates a reusable state machine. I've simplified our machine to locate the error being the not function:

import { not, setup } from 'xstate';

export const myMachine = setup({
  guards: {
    myGuard: () => true,
  },
}).createMachine({
  states: {
    foo: {
      on: {
        someEvent: {
          target: 'bar',
          guard: not('myGuard'),
        },
      },
    },
    bar: {},
  },
});

Expected result

I expected the typings to be built without issues.

Actual result

When trying to build types for the packages, I get the following error:

src/my-machine.ts:3:14 - error TS2742: The inferred type of 'myMachine' cannot be named without a reference to '../../../node_modules/xstate/dist/declarations/src/guards'. This is likely not portable. A type annotation is necessary.

3 export const myMachine = setup({

It seems like the issue stems from the not function referencing the GuardPredicate type which is not exported by XState and TypeScript is unable to build a type for it without this reference.

Reproduction

https://codesandbox.io/p/devbox/angry-goldberg-v42j8m?workspaceId=4a3e8946-02ff-4af1-aeb6-deeb01d9e58a

Additional context

Try running pnpm run build in the reproduction and you will see the error. For some reason, the error doesn't occur when using...

"moduleResolution": "node",

...in tsconfig.json. But that doesn't seem like a viable solution as that causes other module issues and is not really recommended by TS at this point.

flugg commented 2 months ago

I also found this issue which seems to have the same issue, but was closed without further investigation.

And as the reproduction above seems to prove, this doesn't seem to have anything to do with the size of the machines.

Loque- commented 1 month ago

I think I just encountered this issue when trying the machine from here: https://github.com/Devessier/xstatebyexample/blob/main/src/examples/video-player/machine.ts with

"typescript": "5.6.2",
"xstate": "^5.18.2"

I found adding;

// @ts-ignore: 'is declared but its value is never read'
import { Guard } from 'xstate/guards';

resolved the squiggly line, which I considered after this explanation: https://github.com/microsoft/TypeScript/pull/58176#issuecomment-2052698294

boneskull commented 2 hours ago

I created #5046 and I was not able to track down a minimal way to reproduce the problem.

@Loque-'s workaround works for me. You don't even need Guard though:

import 'xstate/guards';

Can anyone (@Loque-, @flugg) reproduce this problem in an XState version older than 5.17.1?