@nest-toolbox/open-api-spec-to-ts
Generate TypeScript interfaces and enums from your OpenAPI (Swagger) specifications. Powered by json-schema-to-typescript.
Installationโ
npm install @nest-toolbox/open-api-spec-to-ts
Quick Startโ
import { generate } from '@nest-toolbox/open-api-spec-to-ts';
// Generate TypeScript interfaces from an OpenAPI spec
await generate('./openapi.json', './src/interfaces');
Given an openapi.json with component schemas, this creates:
- One
.tsfile per schema (e.g.,User.ts,Article.ts) - An
index.tsbarrel file that re-exports everything - Auto-generated import statements between related interfaces
Featuresโ
- ๐ One file per schema โ each OpenAPI component schema gets its own TypeScript file
- ๐ Automatic imports โ cross-references between schemas are resolved into proper import statements
- ๐ฆ Barrel file โ generates an
index.tsthat re-exports all interfaces - ๐ท๏ธ Enum support โ string enums are converted to TypeScript enums with UPPER_SNAKE_CASE names
- ๐ Self-reference handling โ schemas that reference themselves are handled correctly
- ๐งน Clean output โ removes existing files before regenerating
- ๐ Configurable verbosity โ control logging output with
LogLevel - ๐จ Customizable formatting โ pass
json-schema-to-typescriptoptions for code style control
API Referenceโ
generate(openApiFilePath, interfacesDirPath, options?)โ
The main function that reads an OpenAPI spec and generates TypeScript files.
import { generate, LogLevel } from '@nest-toolbox/open-api-spec-to-ts';
await generate(
'./openapi.json', // path to your OpenAPI spec
'./src/interfaces', // output directory for generated files
{
verbosity: LogLevel.INFO,
style: {
singleQuote: true,
semi: true,
tabWidth: 2,
},
},
);
Parametersโ
| Parameter | Type | Default | Description |
|---|---|---|---|
openApiFilePath | string | './openapi.json' | Path to the OpenAPI JSON specification file |
interfacesDirPath | string | './interfaces' | Output directory for generated TypeScript files |
options | Partial<Options> | {} | Generation options (see below) |
Optionsโ
Extends json-schema-to-typescript's Options with additional fields:
| Option | Type | Default | Description |
|---|---|---|---|
verbosity | LogLevel | LogLevel.NONE | Logging level (NONE, ERROR, INFO) |
bannerComment | string | '' | Comment added to the top of each file |
declareExternallyReferenced | boolean | false | Include externally referenced types inline |
enableConstEnums | boolean | false | Generate const enum instead of enum |
unknownAny | boolean | false | Use unknown instead of any |
strictIndexSignatures | boolean | false | Use strict index signatures |
style.singleQuote | boolean | true | Use single quotes |
style.semi | boolean | true | Include semicolons |
style.tabWidth | number | 4 | Indentation width |
style.printWidth | number | 120 | Max line width |
style.useTabs | boolean | false | Use tabs instead of spaces |
style.bracketSpacing | boolean | true | Spaces inside object braces |
LogLevelโ
Enum controlling console output verbosity.
import { LogLevel } from '@nest-toolbox/open-api-spec-to-ts';
LogLevel.NONE // 0 โ no output
LogLevel.ERROR // 1 โ errors only
LogLevel.INFO // 2 โ errors + info messages
Examplesโ
Basic generation scriptโ
// scripts/generate-types.ts
import { generate, LogLevel } from '@nest-toolbox/open-api-spec-to-ts';
async function main() {
await generate('./docs/openapi.json', './src/generated/api-types', {
verbosity: LogLevel.INFO,
});
console.log('Done!');
}
main();
Add to your package.json:
{
"scripts": {
"generate:types": "ts-node scripts/generate-types.ts"
}
}
CLI-style usage with argumentsโ
// scripts/generate-types.ts
import { generate, LogLevel } from '@nest-toolbox/open-api-spec-to-ts';
import { argv } from 'yargs';
const openApiFilePath = argv.openApiPath as string || './openapi.json';
const interfacesDirPath = argv.interfacesPath as string || './interfaces';
const verbosity = (argv.verbosity as LogLevel) || LogLevel.INFO;
generate(openApiFilePath, interfacesDirPath, { verbosity });
npx ts-node scripts/generate-types.ts \
--openApiPath='./docs/api-spec.json' \
--interfacesPath='./src/types'
Generated output structureโ
Given an OpenAPI spec with these schemas:
{
"components": {
"schemas": {
"User": {
"type": "object",
"properties": {
"id": { "type": "number" },
"name": { "type": "string" },
"role": { "$ref": "#/components/schemas/Role" }
}
},
"Role": {
"type": "string",
"enum": ["admin", "user", "guest"]
}
}
}
}
The generator produces:
src/interfaces/
โโโ index.ts # export * from './User';
โ # export * from './Role';
โโโ User.ts # import { Role } from './';
โ # export interface User { id: number; name: string; role: Role; }
โโโ Role.ts # export enum Role { ADMIN = 'admin', USER = 'user', GUEST = 'guest' }
Custom formattingโ
await generate('./openapi.json', './src/types', {
verbosity: LogLevel.INFO,
unknownAny: true, // use `unknown` instead of `any`
enableConstEnums: true, // generate const enums
style: {
singleQuote: true,
semi: false, // no semicolons
tabWidth: 2,
printWidth: 80,
},
});
Integration with NestJS build pipelineโ
// scripts/prebuild.ts
import { generate, LogLevel } from '@nest-toolbox/open-api-spec-to-ts';
async function prebuild() {
// Generate types from the API spec before compilation
await generate(
'./docs/openapi.json',
'./src/generated/api-types',
{ verbosity: LogLevel.INFO },
);
}
prebuild();
{
"scripts": {
"prebuild": "ts-node scripts/prebuild.ts",
"build": "nest build"
}
}