xstate icon indicating copy to clipboard operation
xstate copied to clipboard

[Typescript] `StateValue` is not typesafe

Open mrchantey opened this issue 3 years ago • 0 comments

Description

Working with machine.transition() and other implementations of StateValue, the type is not provided. The type safety is provided elsewhere, ie state.matches:

TSV extends TResolvedTypesMeta extends TypegenEnabled
      ? Prop<Prop<TResolvedTypesMeta, 'resolved'>, 'matchesStates'>
      : never

It would be great to see this applied more broadly.

Expected result

Here is an example implementation with a generic StateValue. Naturally a lot of this code is to get at the typegen that would be already available within the StateNode class.

type AnyTypegen = ResolveTypegenMeta<any, any, any, any>;
type GetTypegen<T extends AnyStateMachine> = T extends StateMachine<any,any,any,any,any,any,infer T2>
  ? T2 extends AnyTypegen ? T2["resolved"] : never : never;
type StateValue<T extends AnyStateMachine> = GetTypegen<T>["matchesStates"];

const transitionSafely = <T extends AnyStateMachine>(
  machine: T,
  state: StateValue<T>,
  event: any
) => machine.transition(state, event).value as StateValue<T>;

Actual result

//'foo' should be a typescript error, and value should be 'inactive|active'
const value1 = machine.transition("foo", "TOGGLE").value;

Reproduction

https://codesandbox.io/s/xstate-typescript-demo-le9xqo?file=/src/index.ts

Additional context

No response

mrchantey avatar Aug 08 '22 02:08 mrchantey