0Pricing
TypeScript Academy · Lesson

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 inspector

Recap: 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

  1. Typing Redux Toolkit Slices and Thunks
  2. Zustand Store Typing Patterns
  3. XState: Typed State Machines
  4. Derived State and Selectors with Types
← Back to TypeScript Academy