Types Roadmap
See original GitHub issue-
Provide a hack-free safe degraded version of types. Because the currect depend on some likely typescript non-guarantees that might break, So if some users would like to trade safety over precise types and developer experience they can use that version. And we can also be less worried of making workarounds because we have already warned “Hey this might break” 😛 Two ways of going about this -
@cassionzen/usestatemachine/safe
(temporary name)-
Alternative names to “safe” - workaroundFree, hackFree, Current workarounds -declare module "@cassionzen/usestatemachine" { interface TypeOptions { safe: true } }
InferNarrowestObject
which is almost same as this andDefinition.FromTypeParameter
(TODO: document what’s happening here)
For milestone v1.0.0
-
Support guard’s that are actually typed as type guards. Meaning this should work -
const eventHasFoo = (state: { event: { foo?: string | undefined } }): state is { event: { foo: string } } => typeof state.event.foo !== "undefined" // I always wanted to publish a library provides authoring predicates that infer guards, which I might :P // Meaning with that library the above can be replaced by something like // let eventHasFoo = P.doesHave("event.foo", P.isNotUndefined) // and if they write it in the machine itself (which they should) they'd also get completions and errors via contextual inferrence. useStateMachine({ schema: { events: { X: t<{ foo?: string | undefined }> } }, initial: "a", states: { a: { on: { X: { target: "b", gaurd: eventHasFoo } }, b: { effect: ({ event }) => { let x: string = event.foo // without `gaurd: eventHasFoo` foo would have been `string | undefined` } } } })
It’s great the signature is
({ context, event }) => ...
instead of(context, event) => ...
like xstate, because latter is principally incorrect and consequently has some consFor milestone v1.1.0
-
Provide (probably opt-in) linting
-
noInitialToDeadStateNodes
// needs to be written once per (tsconfig) project declare module "@cassionzen/usestatemachine" { interface TypeOptions { noInitialToDeadStateNodes: true } } useStateMachine({ initial: "b", // Error(noInitialToDeadStateNodes): "b" is a dead state node states: { a: { on: { X: "b" } }, b: {} } })
-
noNonExhaustiveEventsSchema
-useStateMachine({ schema: { events: { // Error(noNonExhaustiveEventsSchema): `$$exhaustive` not set to `true` X: t<{ foo: string }>() } } })
-
noSchemalessDefintion
useStateMachine({ // Error(noSchemalessDefintion): `schema` is not set initial: "a", states: { a: {} } })
- more? I don’t use state machines so I’m not sure what else we could come up with haha
For milestone v1.2.0
-
-
more?
Issue Analytics
- State:
- Created 2 years ago
- Comments:26 (26 by maintainers)
Yeah my impression of the spec is similar and I never meant following the spec exactly - what I meant was let’s not do something too out of the way and we aren’t as you said the transition behavior is going to be same. And anyways you’re more expert at this than me so no worries about that 😛
Cool then we’ll keep this for a later release, so this will be my next task after I’m done with
lite-types
.I think these lint rules already go a long way. I can’t think of any others. The “more” that I referred to was for the 1.2.0 release (or later) 😁
Very true. The types need to support that, and I’ll work on the “runtime” code.