0
# OpenAPI Utilities
1
2
Advanced type utilities for extracting and manipulating OpenAPI path and operation objects, including request/response type extraction and content filtering.
3
4
## Capabilities
5
6
### Path Utilities
7
8
#### Paths with Method Extractor
9
10
Find all paths that have the given HTTP method.
11
12
```typescript { .api }
13
/**
14
* Given an OpenAPI Paths Object, find all paths that have the given method
15
*/
16
type PathsWithMethod<Paths extends {}, PathnameMethod extends HttpMethod> = {
17
[Pathname in keyof Paths]: Paths[Pathname] extends {
18
[K in PathnameMethod]: any;
19
}
20
? Pathname
21
: never;
22
}[keyof Paths];
23
```
24
25
**Usage Examples:**
26
27
```typescript
28
import type { PathsWithMethod, HttpMethod } from "openapi-typescript-helpers";
29
30
// Define OpenAPI paths
31
type ApiPaths = {
32
"/users": {
33
get: { responses: { 200: { content: { "application/json": User[] } } } };
34
post: { requestBody: any; responses: { 201: any } };
35
};
36
"/posts": {
37
get: { responses: { 200: any } };
38
};
39
"/admin": {
40
put: { requestBody: any; responses: { 200: any } };
41
delete: { responses: { 204: any } };
42
};
43
};
44
45
// Extract paths that support specific methods
46
type GetPaths = PathsWithMethod<ApiPaths, "get">; // "/users" | "/posts"
47
type PostPaths = PathsWithMethod<ApiPaths, "post">; // "/users"
48
type DeletePaths = PathsWithMethod<ApiPaths, "delete">; // "/admin"
49
```
50
51
### Operation Object Types
52
53
#### Operation Object Interface
54
55
Internal interface for OpenAPI operation objects.
56
57
```typescript { .api }
58
/**
59
* DO NOT USE!
60
* Only used for OperationObject type inference
61
*/
62
interface OperationObject {
63
parameters: any;
64
requestBody: any;
65
responses: any;
66
}
67
```
68
69
#### Path Item Object
70
71
Internal helper for path item objects.
72
73
```typescript { .api }
74
/**
75
* Internal helper used in PathsWithMethod
76
*/
77
type PathItemObject = {
78
[M in HttpMethod]: OperationObject;
79
} & { parameters?: any };
80
```
81
82
### Response Utilities
83
84
#### Response Object Map Extractor
85
86
Return responses for an Operation Object.
87
88
```typescript { .api }
89
/**
90
* Return `responses` for an Operation Object
91
*/
92
type ResponseObjectMap<T> = T extends { responses: any } ? T["responses"] : unknown;
93
```
94
95
#### Response Content Extractor
96
97
Return content for a Response Object.
98
99
```typescript { .api }
100
/**
101
* Return `content` for a Response Object
102
*/
103
type ResponseContent<T> = T extends { content: any } ? T["content"] : unknown;
104
```
105
106
#### Success Response Extractor
107
108
Return all 2XX responses from a Response Object Map.
109
110
```typescript { .api }
111
/**
112
* Return all 2XX responses from a Response Object Map
113
*/
114
type SuccessResponse<
115
T extends Record<string | number, any>,
116
Media extends MediaType = MediaType,
117
> = GetResponseContent<T, Media, OkStatus>;
118
```
119
120
**Usage Examples:**
121
122
```typescript
123
import type { SuccessResponse, ResponseObjectMap } from "openapi-typescript-helpers";
124
125
// Define operation response
126
type UserOperation = {
127
responses: {
128
200: { content: { "application/json": User; "text/plain": string } };
129
201: { content: { "application/json": User } };
130
400: { content: { "application/json": { error: string } } };
131
};
132
};
133
134
// Extract success responses
135
type UserSuccess = SuccessResponse<ResponseObjectMap<UserOperation>>;
136
// Result: User | string (from 200) | User (from 201)
137
138
// Filter by media type
139
type UserSuccessJSON = SuccessResponse<ResponseObjectMap<UserOperation>, "application/json">;
140
// Result: User
141
```
142
143
#### Error Response Extractor
144
145
Return all 5XX and 4XX responses from a Response Object Map.
146
147
```typescript { .api }
148
/**
149
* Return all 5XX and 4XX responses (in that order) from a Response Object Map
150
*/
151
type ErrorResponse<
152
T extends Record<string | number, any>,
153
Media extends MediaType = MediaType,
154
> = GetResponseContent<T, Media, ErrorStatus>;
155
```
156
157
#### JSON Response Extractors
158
159
Extract JSON-like responses for success and error cases.
160
161
```typescript { .api }
162
/**
163
* Return first JSON-like 2XX response from a path + HTTP method
164
*/
165
type SuccessResponseJSON<PathMethod extends Record<string | number, any>> = SuccessResponse<
166
ResponseObjectMap<PathMethod>,
167
`${string}/json`
168
>;
169
170
/**
171
* Return first JSON-like 5XX or 4XX response from a path + HTTP method
172
*/
173
type ErrorResponseJSON<PathMethod extends Record<string | number, any>> = ErrorResponse<
174
ResponseObjectMap<PathMethod>,
175
`${string}/json`
176
>;
177
```
178
179
**Usage Examples:**
180
181
```typescript
182
import type { SuccessResponseJSON, ErrorResponseJSON } from "openapi-typescript-helpers";
183
184
// Define path method
185
type GetUser = {
186
responses: {
187
200: {
188
content: {
189
"application/json": User;
190
"application/xml": string;
191
};
192
};
193
404: {
194
content: {
195
"application/json": { error: string };
196
"text/plain": string;
197
};
198
};
199
};
200
};
201
202
// Extract JSON responses only
203
type UserData = SuccessResponseJSON<GetUser>; // User
204
type UserError = ErrorResponseJSON<GetUser>; // { error: string }
205
```
206
207
### Request Body Utilities
208
209
#### Operation Request Body Extractor
210
211
Return type of requestBody for an Operation Object.
212
213
```typescript { .api }
214
/**
215
* Return type of `requestBody` for an Operation Object
216
*/
217
type OperationRequestBody<T> = "requestBody" extends keyof T ? T["requestBody"] : never;
218
```
219
220
#### Request Body Optional Check
221
222
Resolve to true if request body is optional, else false.
223
224
```typescript { .api }
225
/**
226
* Resolve to `true` if request body is optional, else `false`
227
*/
228
type IsOperationRequestBodyOptional<T> = RequiredKeysOf<PickRequestBody<T>> extends never ? true : false;
229
```
230
231
#### Request Body Content Extractor
232
233
Return first content from a Request Object Mapping, allowing any media type.
234
235
```typescript { .api }
236
/**
237
* Return first `content` from a Request Object Mapping, allowing any media type
238
*/
239
type OperationRequestBodyContent<T> = FilterKeys<OperationRequestBodyMediaContent<T>, MediaType> extends never
240
? FilterKeys<NonNullable<OperationRequestBodyMediaContent<T>>, MediaType> | undefined
241
: FilterKeys<OperationRequestBodyMediaContent<T>, MediaType>;
242
```
243
244
#### JSON Request Body Extractor
245
246
Return JSON-like request body from a path + HTTP method.
247
248
```typescript { .api }
249
/**
250
* Return JSON-like request body from a path + HTTP method
251
*/
252
type RequestBodyJSON<PathMethod> = JSONLike<FilterKeys<OperationRequestBody<PathMethod>, "content">>;
253
```
254
255
**Usage Examples:**
256
257
```typescript
258
import type {
259
OperationRequestBody,
260
IsOperationRequestBodyOptional,
261
RequestBodyJSON
262
} from "openapi-typescript-helpers";
263
264
// Define operation with request body
265
type CreateUser = {
266
requestBody: {
267
content: {
268
"application/json": { name: string; email: string };
269
"application/xml": string;
270
};
271
};
272
responses: { 201: { content: { "application/json": User } } };
273
};
274
275
// Extract request body
276
type CreateUserBody = OperationRequestBody<CreateUser>;
277
// Result: { content: { "application/json": {...}, "application/xml": string } }
278
279
// Check if optional
280
type IsOptional = IsOperationRequestBodyOptional<CreateUser>; // false
281
282
// Extract JSON body
283
type CreateUserJSON = RequestBodyJSON<CreateUser>; // { name: string; email: string }
284
```
285
286
### Internal Helper Types
287
288
#### Request Body Picker
289
290
Internal helper to get object type with only the requestBody property.
291
292
```typescript { .api }
293
/**
294
* Internal helper to get object type with only the `requestBody` property
295
*/
296
type PickRequestBody<T> = "requestBody" extends keyof T ? Pick<T, "requestBody"> : never;
297
```
298
299
#### Operation Request Body Media Content
300
301
Internal helper used in OperationRequestBodyContent.
302
303
```typescript { .api }
304
/**
305
* Internal helper used in OperationRequestBodyContent
306
*/
307
type OperationRequestBodyMediaContent<T> = IsOperationRequestBodyOptional<T> extends true
308
? ResponseContent<NonNullable<OperationRequestBody<T>>> | undefined
309
: ResponseContent<OperationRequestBody<T>>;
310
```
311
312
#### Get Response Content
313
314
Internal helper for extracting response content with media type filtering.
315
316
```typescript { .api }
317
/**
318
* Internal helper used for response content extraction
319
*/
320
type GetResponseContent<
321
T extends Record<string | number, any>,
322
Media extends MediaType = MediaType,
323
ResponseCode extends keyof T = keyof T,
324
> = ResponseCode extends keyof T
325
? {
326
[K in ResponseCode]: T[K]["content"] extends Record<string, any>
327
? FilterKeys<T[K]["content"], Media> extends never
328
? T[K]["content"]
329
: FilterKeys<T[K]["content"], Media>
330
: K extends keyof T
331
? T[K]["content"]
332
: never;
333
}[ResponseCode]
334
: never;
335
```