OpenAPI to TypeScript Types Generator

Extract the schema objects from an OpenAPI 3.x (components.schemas) or Swagger 2.0 (definitions) document and get matching TypeScript types. $refs become named references, enums become string-literal unions or real enums, nullable and 3.1 ["string","null"] become unions, and descriptions become JSDoc. Paste JSON or YAML — everything runs in your browser, no upload, no sign-up.

Try:
TypeScript

About this tool

Paste an OpenAPI 3.x or Swagger 2.0 document and get back TypeScript type declarations for every schema it defines. The generator reads the components.schemas object (OpenAPI 3.x) or the top-level definitions object (Swagger 2.0), then walks each schema into a matching TypeScript type — no install, no server, no account. Everything runs locally in your browser.

It understands the JSON-Schema constructs OpenAPI relies on: $ref (rendered as a reference to the named type), enum and const, nullable and the OpenAPI 3.1 type: ["string", "null"] form (both become unions), required (drives the ? optional marker), properties and additionalProperties (index signatures), array items and tuple prefixItems, and allOf / oneOf / anyOf (intersection and union types). Schema descriptions become JSDoc comments.

Worked example

Input (YAML):

openapi: "3.0.3"
components:
  schemas:
    Status:
      type: string
      enum: [active, banned]
    User:
      type: object
      required: [id, name]
      properties:
        id: { type: integer }
        name: { type: string }
        status: { $ref: "#/components/schemas/Status" }
        tags: { type: array, items: { type: string } }

Output (default settings — interface declarations, union enums):

export type Status = "active" | "banned";

export interface User {
  id: number;
  name: string;
  status?: Status;
  tags?: string[];
}

id and name are required so they have no ?; status and tags are not in required, so they are optional. Status is emitted as a string-literal union; switch String enums as to enum to get a real export enum Status { … } instead.

Options

FAQ

Which part of the OpenAPI document does it convert?

Only the reusable schema objects: components.schemas for OpenAPI 3.x, or the top-level definitions for Swagger 2.0. It does not generate a request client from paths / operations, and it does not read parameters, requestBody, or responses inline schemas — put your models under components.schemas (the standard place) and reference them with $ref.

How are optional and nullable properties handled?

Optional and nullable are two different things in OpenAPI, and this tool keeps them separate. A property is optional (name?: string) when it is not listed in the schema's required array — that is the Property optionality: spec default. A property is nullable (name: string | null) when the schema sets nullable: true (OpenAPI 3.0) or uses type: ["string", "null"] (OpenAPI 3.1). A field can be both, neither, or either.

Does it resolve $ref and external files?

Local $refs like #/components/schemas/User are resolved to the matching TypeScript type name, so your types stay cross-linked. External $refs (another file or URL, e.g. ./common.yaml#/Address) are not fetched — only the last path segment is used as the type name, and no declaration is emitted for it. Bundle your spec into a single document first (with a tool like swagger-cli bundle) if it splits schemas across files.

What TypeScript does an empty or free-form object become?

An object schema with no properties becomes a Record<…>: Record<string, unknown> for a plain or additionalProperties: true object, Record<string, T> when additionalProperties is itself a schema, and Record<string, never> when additionalProperties: false. An object that has properties and additionalProperties gets both the named fields and an [key: string]: … index signature.

What about validation keywords like pattern, minimum, or format?

TypeScript's type system can't express runtime constraints, so JSON-Schema validation keywords (pattern, minimum/maximum, minLength, multipleOf, format, …) are ignored — a string with a format: email is still string. The output describes the shape of your data, not its runtime validity. If you need runtime validation, generate a schema-aware validator separately.

Limits and edge cases

Developer & Automation Access

Run it from the terminal

Same engine as this page, headless — via the gizza CLI:

gizza tool openapi-to-typescript-types 'openapi: "3.0.3"
components:
  schemas:
    User:
      type: object
      required: [id]
      properties:
        id: { type: integer }
        name: { type: string }'

New to the CLI? Get gizza →

Open it by URL

Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:

https://gizza.ai/tools/openapi-to-typescript-types/?spec=openapi%3A%20%223.0.3%22%0Acomponents%3A%0A%20%20schemas%3A%0A%20%20%20%20User%3A%0A%20%20%20%20%20%20type%3A%20object%0A%20%20%20%20%20%20required%3A%20%5Bid%5D%0A%20%20%20%20%20%20properties%3A%0A%20%20%20%20%20%20%20%20id%3A%20%7B%20type%3A%20integer%20%7D%0A%20%20%20%20%20%20%20%20name%3A%20%7B%20type%3A%20string%20%7D&input_format=auto&declaration=interface&enum_style=union&optional_style=spec&export=true&readonly=true&sort=true&indent=2

Machine-readable descriptor: tool.json — title + parameters JSON Schema for agents.