Skip to content
Version: XState v4

Type helpers

XState makes several type helpers available to you for composing types in TypeScript. You can use these helpers for creating custom functions or typing various integrations.

SnapshotFrom​

SnapshotFrom can be used to extract the State from a machine.

import { createMachine, SnapshotFrom } from 'xstate';

const machine = createMachine({
schema: {
context: {} as {
count: number;
},
},
});

const myFunction = (snapshot: SnapshotFrom<typeof machine>) => {
const context = state.context;
};

ContextFrom​

ContextFrom can be used to extract the context from a machine.

import { createMachine, ContextFrom } from 'xstate';

const machine = createMachine({
schema: {
context: {} as {
count: number;
},
},
});

const myFunction = (context: ContextFrom<typeof machine>) => {
console.log(context);
};

EventFrom​

EventFrom can be used to extract the event types from a machine

import { createMachine, EventFrom } from 'xstate';

const machine = createMachine({
schema: {
events: {} as
| {
type: 'FOO';
}
| {
type: 'BAR';
value: string;
},
},
});

const myFunction = (event: EventFrom<typeof machine>) => {
console.log(event);
};

You can also extract specific events by passing the type to the second generic slot.

import { createMachine, EventFrom } from 'xstate';

const machine = createMachine({
schema: {
events: {} as
| {
type: 'FOO';
}
| {
type: 'BAR';
value: string;
},
},
});

const myFunction = (event: EventFrom<typeof machine, 'BAR'>) => {
console.log(event);
};

InterpreterFrom​

InterpreterFrom gives you the type of the actor returned from interpret or useInterpret.

import { createMachine, InterpreterFrom } from 'xstate';

const machine = createMachine({
schema: {
context: {} as {
count: number;
},
},
});

const myFunction = (actor: InterpreterFrom<typeof machine>) => {
const context = actor.state.context;
};

ActorRefFrom​

ActorRefFrom is especially useful when spawning actors because it types the reference created by spawn when assigning to context.

import { createMachine, ActorRefFrom, spawn, assign } from 'xstate';

const childMachine = createMachine({});

const machine = createMachine({
schema: {
context: {} as {
spawnedChild: ActorRefFrom<typeof childMachine>;
},
},
entry: [
assign((context, event) => {
return {
spawnedChild: spawn(childMachine),
};
}),
],
});

MachineOptionsFrom​

You can use MachineOptionsFrom in combination with typegen to get a strongly typed version of the machine’s options.

export interface Typegen0 {
'@@xstate/typegen': true;
eventsCausingActions: {
sayHello: 'xstate.init';
};
internalEvents: {
'xstate.init': { type: 'xstate.init' };
};
invokeSrcNameMap: {};
missingImplementations: {
actions: 'sayHello' | 'sayHelloAgain';
actors: never;
guards: never;
delays: never;
};
eventsCausingactors: {};
eventsCausingGuards: {};
eventsCausingDelays: {};
matchesStates: undefined;
tags: never;
}

import { createMachine, MachineOptionsFrom } from 'xstate';

const machine = createMachine({
schema: {
context: {} as {
count: number;
},
},
entry: ['sayHello', 'sayHelloAgain'],
tsTypes: {} as import('./myMachine.typegen').Typegen0,
});

const options: MachineOptionsFrom<typeof machine> = {
actions: {
sayHello: (context) => {},
},
};

You can also pass true to the second element of the generic to ensure that all missing implementations are passed. In the example below, sayGoodbye is missing, so must be passed when you pass true to MachineOptionsFrom.

export interface Typegen0 {
'@@xstate/typegen': true;
eventsCausingActions: {
sayHello: 'xstate.init';
};
internalEvents: {
'xstate.init': { type: 'xstate.init' };
};
invokeSrcNameMap: {};
missingImplementations: {
actions: 'sayGoodbye';
actors: never;
guards: never;
delays: never;
};
eventsCausingactors: {};
eventsCausingGuards: {};
eventsCausingDelays: {};
matchesStates: undefined;
tags: never;
}

import { createMachine, MachineOptionsFrom } from 'xstate';

const machine = createMachine(
{
entry: ['sayHello'],
exit: ['sayGoodbye'],
tsTypes: {} as import('./myMachine.typegen').Typegen0,
},
{
actions: {
sayHello: () => {
console.log('Hello');
},
},
},
);

const options: MachineOptionsFrom<typeof machine, true> = {
actions: {
/**
* This MUST be passed because of the `true` passed in above
*/
sayGoodbye: () => {},
},
};