useMachine с TypeScript выдает ошибку TypeScript о несовпадении типов
Я следовал простому примеру на https://github.com/carloslfu/use-machine, чтобы создать свой первый пример для конечной машины xstate, и застрял со следующей ошибкой машинописного текста:
Argument of type '{ actions: { sideEffect: () => void; }; }' is not assignable to parameter of type 'MachineOptions<TContext, TEvent>'.
Type '{ actions: { sideEffect: () => void; }; }' is missing the following properties from type 'MachineOptions<TContext, TEvent>': guards, activities, services, delays, updater
Вот мой код:
import { MachineConfig, assign } from "xstate";
import { TCreateContext } from "use-machine";
export type TContext = {
counter: number;
};
export type TSchema = {
states: {
Off: {};
On: {};
};
};
export type TEvent = {
type: "Tick";
};
const incAction = assign<TContext>(context => ({
counter: context.counter + 1
}));
export type TMachine = TCreateContext<TContext, TSchema, TEvent>;
export const machineConfig: MachineConfig<TContext, TSchema, TEvent> = {
initial: 'Off',
context: {
counter: 0
},
states: {
Off: { on: { Tick: { target: 'On', actions: [incAction, 'sideEffect'] } } },
On: { on: { Tick: { target: 'Off', actions: incAction } } }
}
}
И чем я просто называю это в компоненте
const machine = useMachine<TContext, TSchema, TEvent>(machineConfig, {
actions: {
sideEffect: () => console.log('sideEffect')
}
})
Есть идеи, что мне не хватает?
Ссылка на выпуск на github.
1 ответ
Как указано на github по ссылке carloslfu и для завершения, вот рабочий пример:
import { MachineConfig } from 'xstate';
import { useMachine } from 'use-machine';
enum SimpleStateNameWithSideEffect {
OFF = 'OFF',
ON = 'ON'
}
interface SimpleStateSchemaWithSideEffect {
states: {
[SimpleStateNameWithSideEffect.OFF]: {};
[SimpleStateNameWithSideEffect.ON]: {};
};
}
enum SimpleActionWithSideEffect {
ACTIVATE = 'ACTIVATE',
DEACTIVATE = 'DEACTIVATE'
}
enum SimpleCallbackActionWithSideEffect {
SWITCHED = 'SWITCHED'
}
type SimpleEventsWithSideEffect =
| { type: SimpleActionWithSideEffect.ACTIVATE }
| { type: SimpleActionWithSideEffect.DEACTIVATE };
interface SimpleContextWithSideEffect {
counter: number;
}
const simpleInitialContextWithSideEffect: SimpleContextWithSideEffect = {
counter: 0
};
const simpleMachineConfigWithSideEffect: MachineConfig<
SimpleContextWithSideEffect,
SimpleStateSchemaWithSideEffect,
SimpleEventsWithSideEffect
> = {
id: 'switch',
initial: SimpleStateNameWithSideEffect.OFF,
states: {
[SimpleStateNameWithSideEffect.OFF]: {
on: {
'': {
target: SimpleStateNameWithSideEffect.ON,
actions: [SimpleCallbackActionWithSideEffect.SWITCHED]
}
}
},
[SimpleStateNameWithSideEffect.ON]: {}
}
};
А затем, как вы бы использовали это в своем компоненте:
const machine = useMachine(
simpleMachineConfigWithSideEffect,
{
actions: {
[SimpleCallbackActionWithSideEffect.SWITCHED]: () =>
console.log('sideEffect')
}
},
simpleInitialContextWithSideEffect
);
Замечание для тех, кто наткнется на это, useMachine также включен в качестве крючка в @xstate/react
библиотека сейчас, для получения дополнительной информации посмотрите пакет на github здесь или на официальной странице документации