How to type transition input in @xstate/store #5017
-
I am using the latest version of const store = createStore(
{ count: 0 },
{
inc: {
count: (context, event: { by: number }) => context.count + event.by,
},
mul: {
count: (context, event: { by2: number }) => context.count * event.by2,
}
},
); I want to create wrappers of transitions, but find it hard to narrow down the transition input types given a fixed const inc = (input: // what type to put here?) => {
store.send({ type: "inc", by: input.by });
};
const mul = (input: // what type to put here?) => {
store.send({ type: "mul", by: input.by2 });
}; Searching through the type IncInput = ExtractEventsFromPayloadMap<{
inc : {
by: number;
};
}> Now But I don't know how to use |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 3 replies
-
Wouldn't it just be this? const inc = (input: number) => {
store.send({ type: "inc", by: input.by });
};
const mul = (input: number) => {
store.send({ type: "mul", by: input.by2 });
}; |
Beta Was this translation helpful? Give feedback.
-
I think you're asking how you could extract the type of each event from the I'm not home right now so I can't try it myself but check out |
Beta Was this translation helpful? Give feedback.
-
I opened #5020 to implement the type export type EventFromStore<TStore extends Store<any, any>> =
TStore extends Store<any, infer TEvent> ? TEvent : never; If that's merged, here's how you could use it to implement what you're looking for: import { createStore, type EventFromStore, type Store } from '@xstate/store';
/**
* Extract the event where `Type` matches the event's `type` from the given
* `Store`.
*/
type EventByType<
TStore extends Store<any, any>,
Type extends EventFromStore<TStore>['type']
> = Extract<EventFromStore<TStore>, { type: Type }>;
/**
* Extract a specific store event's "input" type (the event type without the
* `type` property).
*/
type EventInputByType<
TStore extends Store<any, any>,
Type extends EventFromStore<TStore>['type']
> = Omit<EventByType<TStore, Type>, 'type'>;
const store = createStore(
{ count: 0 },
{
inc: (context, event: { by: number }) => ({
count: context.count + event.by
}),
mul: (context, event: { by2: number }) => ({
count: context.count * event.by2
})
}
);
const inc = (input: EventInputByType<typeof store, 'inc'>) =>
store.send({ type: 'inc', by: input.by });
const mul = (input: EventInputByType<typeof store, 'mul'>) =>
store.send({ type: 'multiply', by2: input.by2 }); Or just add the |
Beta Was this translation helpful? Give feedback.
I opened #5020 to implement the type
EventFromStore
:If that's merged, here's how you could use it to implement what you're looking for: