xstate
xstate copied to clipboard
[Typescript] Bug: Using assign with only partial context causes TS error
Description
When a machine has a context type, attempts to use assign with literal values doesn't work.
Visualizer code for reference:
import { createMachine, assign } from 'xstate';
const assignTSError = createMachine({
id: 'machine',
schema: {
context: {} as { foo: boolean, bar: number }
},
entry: 'assignFooTrue',
context: {
foo: false,
bar: 1,
},
initial: 'ready',
states: {
ready: {},
}
}, {
actions: {
// error
assignFooTrue: assign({
foo: true,
}),
// error
assignFooTrueNoArgs: assign({
foo: () => true,
}),
// ok
assignFooTrueWorking: assign({
foo: (_) => true,
})
}
});
Expected result
I expect this to work:
assignFooTrue: assign({
foo: true,
}),
Actual result
But it causes an error:
Type 'AssignAction<{ foo: boolean; }, EventObject>' is not assignable to type '((context: { foo: boolean; bar: number; }, event: AnyEventObject, meta: ActionMeta<{ foo: boolean; bar: number; }, AnyEventObject, BaseActionObject>) => void) | ActionObject<...> | undefined'.
Type 'AssignAction<{ foo: boolean; }, EventObject>' is not assignable to type 'ActionObject<{ foo: boolean; bar: number; }, AnyEventObject>'.
Types of property 'exec' are incompatible.
Type '((context: { foo: boolean; }, event: EventObject, meta: ActionMeta<{ foo: boolean; }, EventObject, BaseActionObject>) => void) | undefined' is not assignable to type '((context: { foo: boolean; bar: number; }, event: AnyEventObject, meta: ActionMeta<{ foo: boolean; bar: number; }, AnyEventObject, BaseActionObject>) => void) | undefined'.
Type '(context: { foo: boolean; }, event: EventObject, meta: ActionMeta<{ foo: boolean; }, EventObject, BaseActionObject>) => void' is not assignable to type '(context: { foo: boolean; bar: number; }, event: AnyEventObject, meta: ActionMeta<{ foo: boolean; bar: number; }, AnyEventObject, BaseActionObject>) => void'.
Types of parameters 'meta' and 'meta' are incompatible.
Type 'ActionMeta<{ foo: boolean; bar: number; }, AnyEventObject, BaseActionObject>' is not assignable to type 'ActionMeta<{ foo: boolean; }, EventObject, BaseActionObject>'.
The types of 'state.configuration' are incompatible between these types.
Type 'StateNode<{ foo: boolean; bar: number; }, any, AnyEventObject, any, any, TypegenDisabled>[]' is not assignable to type 'StateNode<{ foo: boolean; }, any, EventObject, any, any, TypegenDisabled>[]'.
Type 'StateNode<{ foo: boolean; bar: number; }, any, AnyEventObject, any, any, TypegenDisabled>' is not assignable to type 'StateNode<{ foo: boolean; }, any, EventObject, any, any, TypegenDisabled>'.
The types of 'config.invoke' are incompatible between these types.
Type 'SingleOrArray<AnyStateMachine | InvokeConfig<{ foo: boolean; bar: number; }, AnyEventObject>> | undefined' is not assignable to type 'SingleOrArray<AnyStateMachine | InvokeConfig<{ foo: boolean; }, EventObject>> | undefined'.
Type 'InvokeConfig<{ foo: boolean; bar: number; }, AnyEventObject>' is not assignable to type 'SingleOrArray<AnyStateMachine | InvokeConfig<{ foo: boolean; }, EventObject>> | undefined'.
Type 'InvokeConfig<{ foo: boolean; bar: number; }, AnyEventObject>' is not assignable to type 'InvokeConfig<{ foo: boolean; }, EventObject>'.
Types of property 'src' are incompatible.
Type 'string | AnyStateMachine | InvokeSourceDefinition | InvokeCreator<{ foo: boolean; bar: number; }, AnyEventObject, any, any, AnyEventObject>' is not assignable to type 'string | AnyStateMachine | InvokeSourceDefinition | InvokeCreator<{ foo: boolean; }, EventObject, any, any, EventObject>'.
Type 'InvokeCreator<{ foo: boolean; bar: number; }, AnyEventObject, any, any, AnyEventObject>' is not assignable to type 'string | AnyStateMachine | InvokeSourceDefinition | InvokeCreator<{ foo: boolean; }, EventObject, any, any, EventObject>'.
Type 'InvokeCreator<{ foo: boolean; bar: number; }, AnyEventObject, any, any, AnyEventObject>' is not assignable to type 'InvokeCreator<{ foo: boolean; }, EventObject, any, any, EventObject>'.
Types of parameters 'context' and 'context' are incompatible.
Type '{ foo: boolean; }' is not assignable to type '{ foo: boolean; bar: number; }'.
Reproduction
https://stately.ai/viz/20ac2368-0f36-4688-a3c0-73809d9a1e13
Additional context
No response