Overmind is written in Typescript and it is written with a focus on you dedicating as little time as possible to help Typescript understand what your app is all about. Typescript will spend a lot more time helping you. If you are not a Typescript developer Overmind is a really great project to start learning it as you will get the most out of the little typing you have to do.
Configuration
The only typing you need is the Context. This holds information about your state, actions and effects.
You only have to set up these types once, where you bring your configuration together. That means if you use multiple namespaced configuration you still only create a single Context type.
State
The state you define in Overmind is just an object where you type that object.
When writing Typescript you should not use optional values for your state (?), or use undefined in a union type. In a serializable state store world null is the value indicating “there is no value”.
typeState= {// Do not do this foo?:string// Do not do this foo:string|undefined// Do this foo:string|null// Or this, if there always will be a value there foo:string}exportconststate:State= { foo:null}
Operators is like the action: it can take an optional value, but it always produces a promise output. By default the promised value of an operator is the same as the input.
import { Context, filter } from'overmind'// Actions are interoperable with operators. So type them// like an actionexportconstchangeSomeState= ({ state }:Context) => {state.foo ='bar'}// Most operators takes an action signature, just type it as thatexportconstfilterAwesomeUser=filter((_:Context, user:User) =>user.isAwesome})
When you create a pipe and inline other operators/actions their payloads are inferred. Only the first operator needs to type its payload so that when calling doThis you will have the correct typing for the initial payload.
import { Context, pipe } from'overmind'exportconstdoThis=pipe( (context:Context, value:string) => {// actions.doThis("foo"), requires "string"return123 }, (context:Context, value) => {// value is now "number" })// call actiondoThis('foo') // Typed to string, as first operator needs string