Type ISO Date Strings vs Plain Strings in JSON-to-TypeScript
Use json to typescript with a strategy for date fields — keep them as ISO strings at the type boundary and parse to Date only at the UI edge.
Detailed Explanation
Why "Date" Is the Wrong Type for JSON
JSON.parse() never returns Date instances — it returns strings. Marking a field as Date in your generated type creates a lie that compiles but fails at runtime.
Example JSON
{
"id": "evt_1",
"title": "Conference talk",
"starts_at": "2024-09-12T14:00:00Z",
"ends_at": "2024-09-12T15:30:00Z",
"created_at": "2024-03-01T08:00:00Z"
}
Three Strategies
Strategy 1 — plain string (default, safest):
interface Event {
id: string;
title: string;
starts_at: string;
ends_at: string;
created_at: string;
}
Strategy 2 — branded ISO string (best at scale):
type ISODateString = string & { readonly __brand: "ISODateString" };
interface Event {
id: string;
title: string;
starts_at: ISODateString;
ends_at: ISODateString;
created_at: ISODateString;
}
function asISODate(s: string): ISODateString {
if (!/^\d{4}-\d{2}-\d{2}T/.test(s)) throw new Error("Not ISO 8601");
return s as ISODateString;
}
The brand prevents accidentally passing a free-text string into a function expecting a date string, while keeping the runtime type identical to a JSON string.
Strategy 3 — Date instances (only after a parse step):
interface ParsedEvent {
id: string;
title: string;
starts_at: Date;
ends_at: Date;
created_at: Date;
}
function parseEvent(raw: Event): ParsedEvent {
return { ...raw, starts_at: new Date(raw.starts_at), ends_at: new Date(raw.ends_at), created_at: new Date(raw.created_at) };
}
Use this only for the type that exists after explicit parsing. Mixing raw JSON shapes with Date types in the same interface guarantees runtime crashes.
Recommendation
Generate with Strategy 1, harden critical fields with Strategy 2, and reach for Strategy 3 only inside dedicated parse layers. The boundary is the JSON.parse call — before it, types are strings; after it (with explicit conversion), types may be Dates.
Use Case
Building a calendar UI that consumes event JSON from a Rails API and needs to compute durations, format times in the user's locale, and never accidentally treat a parsed Date as still being JSON.
Try It — JSON to TypeScript
Related Topics
Handle Date Strings When Converting JSON to TypeScript
Type Refinements
Generate Branded Types from JSON IDs in TypeScript
TypeScript Patterns
Convert Stripe Charge JSON to TypeScript Interfaces
Real-World API Schemas
Convert OpenAI Chat Completion JSON to TypeScript
Real-World API Schemas
Type HTTP PATCH Payload Shapes from JSON
TypeScript Patterns