XState: Typed State Machines
Model state machines with TypeScript in XState.
XState: Typed State Machines is a free TypeScript Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the TypeScript Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why XState with TypeScript?
XState models application state as explicit state machines. With TypeScript, states, events, and context are fully typed, preventing invalid state transitions at compile time.
import { createMachine, assign } from "xstate";Defining Machine Types
XState v5 uses type parameters for context, events, and states. Define them before creating the machine.
type TrafficContext = { count: number };
type TrafficEvent =
| { type: "TURN_GREEN" }
| { type: "TURN_YELLOW" }
| { type: "TURN_RED" };Creating a Typed Machine
Pass your context and event types to createMachine for full type checking of states and transitions.
const trafficMachine = createMachine({
types: {} as { context: TrafficContext; events: TrafficEvent },
id: "traffic",
initial: "red",
context: { count: 0 },
states: {
red: { on: { TURN_GREEN: "green" } },
green: { on: { TURN_YELLOW: "yellow" } },
yellow: { on: { TURN_RED: "red" } },
},
});Typed Context with assign
Use assign to update context — TypeScript ensures the returned partial context matches the defined type.
const machine = createMachine({
types: {} as { context: TrafficContext; events: TrafficEvent },
// ...
entry: assign({ count: 0 }),
on: {
TURN_GREEN: {
actions: assign(({ context }) => ({ count: context.count + 1 })),
},
},
});Using the Machine in React
The useMachine hook from @xstate/react returns typed state and send function.
import { useMachine } from "@xstate/react";
function TrafficLight() {
const [state, send] = useMachine(trafficMachine);
// state.value: "red" | "green" | "yellow"
// send: (event: TrafficEvent) => void
return <button onClick={() => send({ type: "TURN_GREEN" })}>Go</button>;
}Typed Guards
Type guard functions receive typed context and event, ensuring conditions are checked against the correct types.
const machine = createMachine({
types: {} as { context: TrafficContext; events: TrafficEvent },
states: {
red: {
on: {
TURN_GREEN: {
guard: ({ context }) => context.count < 10, // context: TrafficContext
target: "green",
},
},
},
},
});Typed Actions
Named actions can be typed by declaring them in the machine config and implementing them via setup.
import { setup } from "xstate";
const machine = setup({
types: {} as { context: TrafficContext; events: TrafficEvent },
actions: {
logTransition: ({ context, event }) => {
console.log(context.count, event.type);
},
},
}).createMachine({ /* ... */ });Parallel States
XState supports parallel (orthogonal) regions. TypeScript tracks state values for parallel states as objects.
states: {
ui: {
type: "parallel",
states: {
modal: { initial: "closed", states: { closed: {}, open: {} } },
tooltip: { initial: "hidden", states: { hidden: {}, visible: {} } },
},
},
}State Matching
Use state.matches() to check the current state — XState types this for known state names.
const [state] = useMachine(trafficMachine);
if (state.matches("green")) {
// TypeScript knows we're in the green state
}XState Inspector
Connect XState Inspector for visual debugging of state machines during development, without losing type safety in production code.
import { inspect } from "@xstate/inspect";
inspect({ iframe: false }); // opens state machine inspectorRecap: XState Typing
XState typed machines define context and event types, use assign for typed context updates, and integrate with React via useMachine for fully typed state and event dispatch.
Quick Check
What does the types property in XState v5 machine config do?
What You Learned
XState with TypeScript gives you fully typed state machines: define context and event types, use assign for typed updates, guard conditions, and actions. The useMachine hook provides typed state and dispatch in React components.
Frequently asked questions
Is the “XState: Typed State Machines” lesson free?
Yes — the full text of “XState: Typed State Machines” is free to read here on the web, and the TypeScript Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the TypeScript Academy course, upgrade to CoddyKit PRO.
What will I learn in “XState: Typed State Machines”?
Model state machines with TypeScript in XState. You practise TypeScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start TypeScript Academy?
No prior experience is required. TypeScript Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “XState: Typed State Machines” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this TypeScript Academy lesson?
Yes. Every TypeScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Typing Redux Toolkit Slices and Thunks
- Zustand Store Typing Patterns
- XState: Typed State Machines
- Derived State and Selectors with Types