function assertCurrentStep( state: State, step: S, ): asserts state is Extract { if (state.step !== step) { throw new InvalidStateTransitionError( `Invalid state transition: expecting ${step}, got ${state.step}`, ) } } class InvalidStateTransitionError extends Error { constructor(message: string) { super(message) this.name = 'InvalidStateTransitionError' } } // For use in a reducer - means that you can ensure that // a transition between two states A and B can only take place // starting in state A, and provides typesafety // function reducer(state: State, action: Action): State { // switch (action.type) { // case 'GO_TO_STEP_2': { // assertCurrentStep(state, 'step 1') // return { // step: 'step 2', // ...action.payload, // } // } // } // }