Skip to content

Commit

Permalink
Added a StateValueFrom helper that can be used to extract valid sta…
Browse files Browse the repository at this point in the history
…te values from a machine (#3234)
  • Loading branch information
Andarist committed Apr 20, 2022
1 parent 780458c commit ce376b3
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/stupid-plums-smile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'xstate': minor
---

Added a `StateValueFrom` helper that can be used to extract valid state values from a machine. This might specifically be useful with typegen because typegenless `state.matches` accepts `any` anyway.
19 changes: 18 additions & 1 deletion packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
TypegenDisabled,
ResolveTypegenMeta,
TypegenConstraint,
AreAllImplementationsAssumedToBeProvided
AreAllImplementationsAssumedToBeProvided,
TypegenEnabled
} from './typegenTypes';

export type AnyFunction = (...args: any[]) => any;
Expand Down Expand Up @@ -1865,3 +1866,19 @@ export type ContextFrom<T> = ReturnTypeOrValue<T> extends infer R
? TContext
: never
: never;

type Matches<TypegenEnabledArg, TypegenDisabledArg> = {
(stateValue: TypegenEnabledArg): any;
(stateValue: TypegenDisabledArg): any;
};

export type StateValueFrom<
TMachine extends AnyStateMachine
> = StateFrom<TMachine>['matches'] extends Matches<
infer TypegenEnabledArg,
infer TypegenDisabledArg
>
? TMachine['__TResolvedTypesMeta'] extends TypegenEnabled
? TypegenEnabledArg
: TypegenDisabledArg
: never;
30 changes: 29 additions & 1 deletion packages/core/test/typeHelpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import {
createMachine,
EventFrom,
interpret,
MachineOptionsFrom
MachineOptionsFrom,
StateValueFrom
} from '../src';
import { createModel } from '../src/model';
import { TypegenMeta } from '../src/typegenTypes';
Expand Down Expand Up @@ -326,3 +327,30 @@ describe('MachineOptionsFrom', () => {
acceptMachineOptions(100);
});
});

describe('StateValueFrom', () => {
it('should return possible state values from a typegened machine', () => {
interface TypesMeta extends TypegenMeta {
matchesStates: 'a' | 'b' | 'c';
}

const machine = createMachine({
tsTypes: {} as TypesMeta
});

function matches(_value: StateValueFrom<typeof machine>) {}

matches('a');
matches('b');
// @ts-expect-error
matches('unknown');
});

it('should return any from a typegenless machine', () => {
const machine = createMachine({});

function matches(_value: StateValueFrom<typeof machine>) {}

matches('just anything');
});
});

0 comments on commit ce376b3

Please sign in to comment.