Output ​
Learn about files generated with @hey-api/openapi-ts
.
TIP
Your actual output depends on your Hey API configuration. It may contain a different number of files and their contents might differ.
Overview ​
If you use the default configuration, your project might look like this.
my-app/
├── node_modules/
├── src/
│ ├── client/
│ │ ├── index.ts
│ │ ├── schemas.gen.ts
│ │ ├── services.gen.ts
│ │ └── types.gen.ts
│ └── index.ts
└── package.json
Each file is an artifact generated by a plugin. This is the default output, we will cover customizing it on this page.
Let's go through each file in the src/client
folder and explain what it looks like, what it does, and how to use it.
TypeScript Interfaces ​
TypeScript interfaces are located in the types.gen.ts
file. This is the only file that does not impact your bundle size and runtime performance. It will get discarded during build time, unless you configured to emit runtime enums.
This file contains three different categories of interfaces created from your OpenAPI specification:
- reusable components
- operation request, response, and error data
- enums
Depending on your input and configuration, some of these categories might be missing or differ in your output (and that's okay!).
export type Pet = {
id?: number;
name: string;
};
export type AddPetData = {
body: Pet;
};
export type AddPetResponse = Pet;
As you can see, everything is exported from types.gen.ts
. You can import individual exports in your application and use them as necessary.
Configuration ​
You can modify the contents of types.gen.ts
by configuring the @hey-api/types
plugin. Note that you must specify the other default plugins to preserve the default output.
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
'@hey-api/schemas', // preserves default output
'@hey-api/services', // preserves default output
{
name: '@hey-api/types',
// ...custom options
},
],
};
Enums ​
By default, @hey-api/openapi-ts
will only emit enums as types. You may want to generate runtime artifacts. A good use case is iterating through possible field values without manually typing arrays. To emit runtime enums, set enums
to a valid option.
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
// ...default plugins
{
enums: false, // default
name: '@hey-api/types',
},
],
};
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
// ...default plugins
{
enums: 'javascript',
name: '@hey-api/types',
},
],
};
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
// ...default plugins
{
enums: 'typescript',
name: '@hey-api/types',
},
],
};
We recommend exporting enums as plain JavaScript objects. TypeScript enums are not a type-level extension of JavaScript and pose typing challenges.
API Services ​
Services are located in the services.gen.ts
file. Services are abstractions on top of clients and serve the same purpose. By default, @hey-api/openapi-ts
will generate a flat service layer. Your choice to use services comes down to personal preferences and bundle size considerations.
Flat Services ​
This is the default setting. Flat services support tree-shaking and can lead to reduced bundle size over duplicated client calls. The function names are generated from operation IDs or operation location.
Class Services ​
Class services do not support tree-shaking which will lead to increased bundle sizes, but some people prefer this option for syntax reasons. The class names are generated from operation tags and method names are generated from operation IDs or operation location.
No Services ​
If you prefer to use clients directly or do not need the service layer, define plugins
manually and omit the @hey-api/services
plugin. Type support for clients is currently limited due to popularity of other options. If you'd like to use this option and need better types, open an issue.
Configuration ​
You can modify the contents of services.gen.ts
by configuring the @hey-api/services
plugin. Note that you must specify the other default plugins to preserve the default output.
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
'@hey-api/schemas', // preserves default output
'@hey-api/types', // preserves default output
{
asClass: false, // default
name: '@hey-api/services',
},
],
};
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
'@hey-api/schemas', // preserves default output
'@hey-api/types', // preserves default output
{
asClass: true,
name: '@hey-api/services',
},
],
};
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
'@hey-api/schemas', // preserves default output
'@hey-api/types', // preserves default output
'@hey-api/services',
],
};
Output ​
Below are different outputs depending on your chosen style. No services approach will not generate the services.gen.ts
file.
import { client, type Options } from '@hey-api/client-fetch';
import type { AddPetData, AddPetError, AddPetResponse } from './types.gen';
export const addPet = (options: Options<AddPetData>) =>
(options?.client ?? client).post<AddPetResponse, AddPetError>({
...options,
url: '/pet',
});
import { client, type Options } from '@hey-api/client-fetch';
import type { AddPetData, AddPetError, AddPetResponse } from './types.gen';
export class PetService {
public static addPet(options: Options<AddPetData>) {
return (options?.client ?? client).post<AddPetResponse, AddPetError>({
...options,
url: '/pet',
});
}
}
Usage ​
This is how you'd make the same request using each approach.
import { addPet } from './client/services.gen';
addPet({
body: {
name: 'Kitty',
},
});
import { PetService } from './client/services.gen';
PetService.addPet({
body: {
name: 'Kitty',
},
});
import { client } from '@hey-api/client-fetch';
client.post({
body: {
name: 'Kitty',
},
url: '/pet',
});
JSON Schemas ​
Schemas are located in the schemas.gen.ts
file. This file contains runtime schemas generated from your OpenAPI specification definitions located in #/components/schemas
. If you're using OpenAPI 3.1, your schemas are fully JSON Schema compliant and can be used with other tools supporting JSON Schema.
Configuration ​
You can modify the contents of schemas.gen.ts
by configuring the @hey-api/schemas
plugin. Note that you must specify the other default plugins to preserve the default output.
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
'@hey-api/services', // preserves default output
'@hey-api/types', // preserves default output
{
name: '@hey-api/schemas',
type: 'json',
},
],
};
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
'@hey-api/services', // preserves default output
'@hey-api/types', // preserves default output
{
name: '@hey-api/schemas',
type: 'form',
},
],
};
export default {
client: '@hey-api/client-fetch',
input: 'path/to/openapi.json',
output: 'src/client',
plugins: [
'@hey-api/services', // preserves default output
'@hey-api/types', // preserves default output
'@hey-api/schemas',
],
};
Output ​
Below is an example output generated in the type: 'form'
style. Disabling schemas will not generate the schemas.gen.ts
file.
export const PetSchema = {
required: ['name'],
properties: {
id: {
type: 'integer',
format: 'int64',
example: 10,
},
name: {
type: 'string',
example: 'doggie',
},
},
type: 'object',
} as const;
Usage ​
A great use case for schemas is client-side form input validation.
import { $Schema } from './client/schemas.gen';
const maxInputLength = $Schema.properties.text.maxLength;
if (userInput.length > maxInputLength) {
throw new Error(`Text length can't exceed ${maxInputLength} characters!`);
}
Index ​
For convenience, every default generated artifact is re-exported from index.ts
. This file is deprecated and will be removed in future releases. We recommend importing types, services, and schemas from their respective files to avoid ambiguity.
import type { Pet } from './client/types.gen';
// or
import type { Pet } from './client';
Client ​
Client package files are located in the client
folder. This folder will include different files depending on which client you're using. This folder isn't generated by default. If you want to bundle client packages into your output, read the Bundling section.
Examples ​
You can view live examples on StackBlitz.
Sponsoring ​
Love Hey API? Please consider becoming a sponsor.