Specifying Where Inference Should Not Happen
Here we're building a
makeFiniteStateMachine function where
state is a string as seen by
TState extends string:
export const makeFiniteStateMachine = <TState extends string>(config: FSMConfig<TState>) => config;
We then put it into an
FSMConfig interface, which looks
0:00 Here we're building a makeFiniteStateMachine function where state is a string, basically, or TState extends string. We're taking that, and we're putting it in an FSMConfig interface. This looks like this. We have TState extends string, where the initial is TState. This is the initial state that your state machine starts in, for instance.
0:22 Here, we have makeFiniteStateMachine. We have states a and b. This is really weird because we've got a TState here in the initial. Then the states here is a Record of TState. It looks like it's not able to be specified. We've got initial. If we hover over this, it looks like the initial state is the only state that we can specify. That's so annoying.
0:54 It looks like, here, there are two competing inference sites, like one here and then one here. We want to tell TypeScript not to infer one of these places. We don't want to infer TState from here. We actually want to infer it from this bit only.
1:14 That's your goal here. In fact, here, this is another really horrible example, where we have states a and b. initial should be either a or b. c shouldn't be allowed, but it's actually just inferring as c. That's your job. There's a little bit of a clue here. There is a useful little utility we can use from ts-toolbelt. See if you can figure out the solution. Good luck