OpenAPI TypeScript Helpers
openapi-typescript-helpers is a utility package providing TypeScript helper types designed to complement types generated by `openapi-typescript`. Its primary purpose is to offer generic type transformations, which are internally leveraged by other packages in the `openapi-ts` ecosystem, such as `openapi-fetch`. The current stable version is `0.1.0`. Given its recent initial release and close ties to `openapi-typescript`, its release cadence is likely tied to major `openapi-typescript` releases and feature additions, though it may not have independent major version bumps as frequently. Key differentiators include its focus on type-level transformations for refining generated OpenAPI types, particularly for handling `readOnly` and `writeOnly` properties, ensuring type safety and correct data handling across different API operations. Unlike `openapi-typescript` which generates the types, this package provides tools to manipulate and refine those generated types for specific application logic.
Common errors
-
Property 'someReadOnlyField' does not exist on type 'Writable<MySchema>'
cause Attempting to assign a `readOnly` field to a `Writable` type, which excludes `readOnly` properties.fixRemove the `readOnly` property from the object being assigned to the `Writable` type, as it's not meant to be written to. Ensure `openapi-typescript` was run with `--read-write-markers`. -
Type 'MySchema' is not assignable to type 'Readable<MySchema>'
cause This error is unlikely to occur directly for `Readable`, as it only removes `writeOnly` properties. However, a similar error might occur if you try to assign a `Readable` type to a context expecting the original schema type that includes `writeOnly` properties if that context strictly requires them for some reason.fixEnsure the target type or function parameter is also expecting a `Readable` type or a type that is compatible with the `writeOnly` properties being excluded. Or, verify that the original schema does not have `writeOnly` properties that are essential for the assignment.
Warnings
- gotcha This package is designed to work with types generated by `openapi-typescript`. Its utility is minimal without a pre-generated `paths` or similar type from `openapi-typescript`.
- gotcha The README explicitly states this package is "not as well-documented as the others" and to "use at your own discretion." This suggests that its API may be less stable or more prone to change in minor versions compared to its parent project.
- gotcha The `Readable` and `Writable` types rely on markers (`$Read<T>` / `$Write<T>`) which are only added to `openapi-typescript` generated types when the `--read-write-markers` flag is enabled. Without this flag, these helpers will have no effect on `readOnly` / `writeOnly` properties.
Install
-
npm install openapi-typescript-helpers -
yarn add openapi-typescript-helpers -
pnpm add openapi-typescript-helpers
Imports
- Readable
import type { Readable } from 'openapi-typescript-helpers'; - Writable
import type { Writable } from 'openapi-typescript-helpers'; - $Read
import type { $Read } from 'openapi-typescript-helpers';
Quickstart
import type { paths } from './my-api'; // Assume this is generated by openapi-typescript
import type { Readable, Writable } from 'openapi-typescript-helpers';
// Example: Define a schema type from openapi-typescript generated types
type Pet = paths['/pets/{petId}']['get']['responses'][200]['content']['application/json'];
// Create a type for a pet when fetching (should not include writeOnly fields)
type ReadablePet = Readable<Pet>;
// Create a type for creating a pet (should not include readOnly fields)
type WritablePet = Writable<Pet>;
interface PetInput { // Simulate a type with readOnly/writeOnly markers
id: $Read<string>;
name: string;
tag?: string;
secretToken: $Write<string>;
}
type FetchablePetInput = Readable<PetInput>; // id, name, tag
type CreatablePetInput = Writable<PetInput>; // name, tag, secretToken
// You would typically use these types in your API client logic:
// async function fetchPet(petId: string): Promise<ReadablePet> { /* ... */ }
// async function createPet(newPet: WritablePet): Promise<ReadablePet> { /* ... */ }
// Demonstrate how the types change
const petToCreate: CreatablePetInput = {
name: 'Buddy',
// id is excluded by Writable
secretToken: process.env.PET_SECRET ?? '' // secretToken is included
};
const fetchedPet: FetchablePetInput = {
id: '123',
name: 'Buddy'
// secretToken is excluded by Readable
};