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: UnifiedArg drops the type of emitter from its "self" property #4836

Open boneskull opened 5 months ago

boneskull commented 5 months ago

XState version

XState version 5

Description

The self prop of UnifiedArg https://github.com/statelyai/xstate/blob/main/packages/core/src/types.ts#L114 is an ActorRef, but only provides the first two type arguments (snapshot and EventObject for events). The third type arg, which is the "emitter", is left to the default value (EventObject).

Expected result

Given the example in this gist, I'd expect that the self value would be assignable to type ActorRef<any, any, EmittedEvents>.

Actual result

index.ts:24:58 - error TS2322: Type 'ActorRef<MachineSnapshot<{ b?: ActorRef<MachineSnapshot<MachineContext, AnyEventObject, {}, {}, string, NonReducibleUnknown>, AnyEventObject, EventObject> | undefined; }, ... 4 more ..., unknown>, AnyEventObject, EventObject>' is not assignable to type 'ActorRef<any, any, EmittedEvents>'.
  Type 'EventObject' is not assignable to type 'EmittedEvents'.
    Types of property 'type' are incompatible.
      Type 'string' is not assignable to type '"BAR"'.

24       b: ({spawn, self}) => spawn('machineB', { input: { a: self } })
                                                            ~

Found 1 error in index.ts:24

Reproduction

https://gist.github.com/boneskull/a4e139896f661dd0a8288b2af2f0f43d

Additional context

This may be an indication of a larger issue. self doesn't seem all that typesafe. For example, this does not fail compilation:

const machineC = setup({
  types: {
    events: {} as {type: 'FOO'},
    emitted: {} as {type: 'BAR'}
  }
}).createMachine({
  entry: ({self}) => {
    self.on('lkjdshfakdjsfh', () => {});
  }
})
Andarist commented 5 months ago

In a sense, this is a duplicate of https://github.com/statelyai/xstate/issues/4485