-
Here's my situation: I want a base machine that contains the bulk of my logic, e.g. const baseMachine = createMachine({
types: {} as BaseSchema,
context: ({input}) => {
...input,
data: {},
},
on: {
UPDATE: { actions: "evaluate" }
}
states: {
// Some state logic
}
}) Then I want to const rangeMachine = baseMachine.provide({
actions: {
evaluate: raise(({ context: {params, data} }) => {
if (data.value > params.maxValue) {
return { type: "ALARM" };
} else if (data.value < params.minValue) {
return { type: "ALARM" };
}
return { type: "RETURN" };
}),
},
}); And this is trivial of course, but I want some nice typings for The obvious potential solution is to instead use const rangeMachine = setup({
types: SlightlyMoreWellDefinedSchema
actions: { ... } // Gives me well-typed arguments to implement with
}).createMachine(baseMachine.config); But I get type-conflicts (even without defining any What I really want to have is an allowable |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 6 replies
-
After some more development I have found the |
Beta Was this translation helpful? Give feedback.
-
It now seems that But my overall feeling of the approach still stands, and especially the part about default implementations in the last comment. I have worked around the issue with a factory function, but am still looking for a more elegant solution. To reiterate, my intuitive feeling is that I would like to |
Beta Was this translation helpful? Give feedback.
-
Here is how I would do it, with strong typings: const baseMachine = setup({
types: {
context: {} as { data: { value: number } }
},
actions: {
evaluate: raise((_, params: { data: { value: number }; minValue: number; maxValue: number }) => {
if (params.data.value > params.maxValue) {
return { type: "ALARM" };
} else if (params.data.value < params.minValue) {
return { type: "ALARM" };
}
return { type: "RETURN" };
})
}
}).createMachine({
context: ({input}) => ({
// ...
data: {
value: 5
}
}),
on: {
UPDATE: { actions: {
type: 'evaluate',
params: ({ context }) => ({
data: context.data,
minValue: 0,
maxValue: 100
})
} }
},
states: {
// Some state logic
}
}) |
Beta Was this translation helpful? Give feedback.
Given the example above, how do we make sure that is correct and that it does use all of the required params (with correct types)?:
I think this "call site" of the
evaluate
just stays unsound unless you configure theparams
types beforehand (insetup
) or at the same time (increateMachine
). TS just can't typecheck this based on the information that is provided later (inprovide
). If you want this kind of generic-ness then factory functions are the only way since it's the only way to make it work in TypeScript.I see now that your example is using
context.params
(and notparams
that belong to an action). However, that doesn't change that muc…