How to convert OpenAPI to TypeScript
By Flavio
Convert an OpenAPI 3.0 or 3.1 document into TypeScript interfaces in the browser, including schemas, parameters, and JSON request and response bodies.
Free toolThis tutorial uses the OpenAPI to TypeScript. It runs in your browser, so open it in another tab and follow along.
To convert OpenAPI to TypeScript, paste an OpenAPI 3.0 or 3.1 document into a converter that writes an interface for each object schema, plus types for the path and query parameters and the JSON bodies.
We’ll use the OpenAPI to TypeScript tool. It runs in the browser. The document is not uploaded. The only URL flag is semi=1, and that only adds semicolons.
The OpenAPI tutorial on this site generates types with the openapi-typescript CLI, from a server that is already running. This page is the smaller job: you already have the document, and you want the types in the browser.
Convert the books document
- Open OpenAPI to TypeScript.
- Click Load sample, or paste your own YAML or JSON.
- Read the notes under the input. They name what the types left out.
- Copy the TypeScript, or download
openapi-types.ts.
The sample is a small books API. Book.year is an integer and it can be null. id is read-only. GET /books takes a query parameter named tag.
openapi: 3.0.3
info:
title: Books
version: "1.0.0"
paths:
/books:
get:
operationId: listBooks
parameters:
- name: tag
in: query
schema:
type: string
responses:
"200":
description: The books
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Book"
post:
operationId: createBook
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/NewBook"
responses:
"201":
description: Created
content:
application/json:
schema:
$ref: "#/components/schemas/Book"
/books/{bookId}:
get:
operationId: getBook
parameters:
- name: bookId
in: path
required: true
schema:
type: string
responses:
"200":
description: One book
content:
application/json:
schema:
$ref: "#/components/schemas/Book"
components:
schemas:
Book:
type: object
required: [id, title]
properties:
id:
type: string
readOnly: true
title:
type: string
year:
type: integer
nullable: true
tags:
type: array
items:
type: string
NewBook:
type: object
required: [title]
properties:
title:
type: string
year:
type: integer
The page writes this:
export interface Book {
id: string // readOnly
title: string
year?: number | null
tags?: string[]
}
export interface NewBook {
title: string
year?: number
}
/** GET /books */
export interface ListBooksParams {
tag?: string
}
/** GET /books */
export type ListBooksResponse200 = Book[]
/** POST /books */
export type CreateBookRequest = NewBook
/** POST /books */
export type CreateBookResponse201 = Book
/** GET /books/{bookId} */
export interface GetBookParams {
bookId: string
}
/** GET /books/{bookId} */
export type GetBookResponse200 = Book
The note on this sample is: integer is typed as number. TypeScript has no integer type.
year is optional because it is not in required. The null comes from nullable: true. id keeps a readOnly comment. The names ListBooks and GetBook come from operationId.
Tick End lines with semicolons and each property ends with ;. That choice is ?semi=1 in the URL. Files up to 1 MB open from Open file.
What the types include
| In the document | In the TypeScript |
|---|---|
Object schema in components.schemas | export interface |
| Other schema | export type |
operationId | The prefix of the parameter, request, and response names |
| Path and query parameters | One interface, path parameters always required |
application/json and types ending in +json | Request and response aliases |
integer | number |
readOnly, writeOnly, deprecated | A comment on that property |
A document that starts with { or [ is parsed as JSON. Anything else is YAML 1.2, so yes and no stay strings.
What stays out
Swagger 2.0 is rejected. So is a file with no openapi field.
Header and cookie parameters are skipped. format, minLength, pattern, and the numeric limits are not copied into the types. additionalProperties: true does not add an index signature. A schema for additionalProperties does. oneOf and anyOf become unions, and discriminator is not checked. allOf becomes an intersection.
A $ref has to point at #/components/schemas in three pointer parts. An external ref becomes unknown. Keywords next to $ref are ignored. webhooks, callbacks, and a path item $ref are skipped.
When a body lists more than one JSON media type, the type comes from the first one. The page says so in the notes.
These types describe the document. They do not check a payload at runtime. For that, Zod parses the value, and the TypeScript guide is the language tour. A sample JSON object, with no OpenAPI file, belongs in JSON to TypeScript. JSON to JSON Schema drafts a schema from an example, and the JSON Schema validator checks a value against one. The shape of JSON itself is in the introduction to JSON.
Try the OpenAPI to TypeScript
Paste an OpenAPI 3.0 or 3.1 document and get TypeScript interfaces for schemas, path and query parameters, and JSON request and response bodies.
Open the OpenAPI to TypeScript →
Related tools
- JSON to TypeScript: Paste JSON and generate TypeScript interfaces with nested types and optional keys — entirely in your browser.
- JSON to JSON Schema Generator: Paste sample JSON and get a JSON Schema with required keys and formats, plus a strict mode for OpenAI Structured Outputs.
- JSON Schema Validator: Validate a JSON document against a JSON Schema in your browser — every error with its path, keyword, and message.
Want me to talk about your product? You can sponsor this site.