Generate Literal Status Unions from JSON for State Machines
Use json to typescript to convert status strings into literal unions like draft | published | archived — the foundation of typed state machines.
Detailed Explanation
Status Strings as State Machine Keys
A status field is rarely an arbitrary string — it is a state in a small machine. Generating a literal union and pairing it with a transition map turns the type system into a state-machine validator.
Example JSON
[
{ "id": 1, "title": "Hello", "status": "draft" },
{ "id": 2, "title": "Welcome", "status": "published" },
{ "id": 3, "title": "Old post", "status": "archived" }
]
Generated TypeScript
type PostStatus = "draft" | "published" | "archived";
interface Post {
id: number;
title: string;
status: PostStatus;
}
Adding the Transition Map
const allowedTransitions: Record<PostStatus, PostStatus[]> = {
draft: ["published"],
published: ["archived"],
archived: [], // terminal
};
function canTransition(from: PostStatus, to: PostStatus): boolean {
return allowedTransitions[from].includes(to);
}
The Record<PostStatus, PostStatus[]> shape forces you to enumerate every state as a key. If you later add "scheduled" to PostStatus, the compiler reports a missing key in allowedTransitions — no silent state explosions.
Exhaustive Rendering
function badge(status: PostStatus) {
switch (status) {
case "draft": return "Draft";
case "published": return "Live";
case "archived": return "Archived";
}
}
Without the union, status: string would let any value reach the function. With the union, every switch is exhaustive (provided you assert never in the default branch when needed).
Generation Tips
- When the converter sees only 3-7 unique values across all samples, prefer a literal union over
string. - Extract the union to its own
typeso it can be reused in transition maps, badge renderers, filter UIs, and database migrations. - Pair the union with a
const STATUSES: PostStatus[] = ["draft", "published", "archived"]so you can iterate at runtime without re-listing the values.
This pattern scales from publishing workflows to order fulfillment, ticket lifecycles, and feature-flag rollouts.
Use Case
Modeling a CMS post lifecycle where draft, published, and archived are the only valid states and accidental transitions like archived → draft must be rejected at compile time.
Try It — JSON to TypeScript
Related Topics
Generate TypeScript Union Types from JSON String Values
Type Refinements
Generate TypeScript Enums from Repeated JSON Values
Type Refinements
JSON to TypeScript Discriminated Union — Result/Error Pattern
Real-World API Schemas
Generate Branded Types from JSON IDs in TypeScript
TypeScript Patterns
Decide Optional vs Required Fields in JSON-to-TypeScript
TypeScript Patterns