openapi-typesafe-fetch 1.0.0-rc.11 → 1.0.0-rc.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,21 @@
2
2
 
3
3
  This package is a fork of `openapi-fetch`. The entries above `0.17.0` are releases of openapi-typesafe-fetch; `0.17.0` and the entries below it are the upstream history up to the fork point (upstream commit `d46a319a`), with `openapi-fetch` versions.
4
4
 
5
+ ## 1.0.0-rc.12
6
+
7
+ ### Patch Changes
8
+
9
+ - [#136](https://github.com/openapi-typesafe/openapi-typesafe/pull/136) [`68ce29a`](https://github.com/openapi-typesafe/openapi-typesafe/commit/68ce29ad4b8f8490d38990af62bbc830b54df015) Thanks [@fedorello](https://github.com/fedorello)! - A wrapper generic in the path that sets `parseAs`, such as
10
+ `client.GET(path, { ...init, parseAs: "text" })` or an `init` typed
11
+ `FetchOptions<…> & { parseAs: "text" }`, types `data` as the body of that `parseAs` again
12
+ (`string` for `"text"`), as openapi-fetch does. Before, it was the text or any JSON body of the
13
+ paths, so assigning it to `string | undefined` failed. Each member of a union of options now
14
+ types its own data: `{ parseAs: ParseAs } | undefined` gives every body, as in openapi-fetch.
15
+
16
+ - [#136](https://github.com/openapi-typesafe/openapi-typesafe/pull/136) [`68ce29a`](https://github.com/openapi-typesafe/openapi-typesafe/commit/68ce29ad4b8f8490d38990af62bbc830b54df015) Thanks [@fedorello](https://github.com/fedorello)! - `SuccessResponseJSON` and `ErrorResponseJSON` of a union of operations are the union of each
17
+ operation's JSON bodies again. Before, only the status codes the operations share counted, so
18
+ `ErrorResponseJSON<OpA | OpB>` could gain a `string` that neither operation has alone.
19
+
5
20
  ## 1.0.0-rc.11
6
21
 
7
22
  ### Patch Changes
@@ -307,15 +307,23 @@ type JSONMediaType = JSONMediaPattern | JSONMediaRange;
307
307
  * parameters, which do not count.
308
308
  */
309
309
  type IsJSONMediaType<Key> = Key extends string ? IsJSONMediaPattern<Key> extends true ? true : MediaSubtype<Lowercase<Key>> extends "*" ? true : false : false;
310
- /** Return first JSON-like 2XX response from a path + HTTP method */
311
- type SuccessResponseJSON<PathMethod extends Record<string | number, any>> = SuccessResponse<ResponseObjectMap<PathMethod>, JSONMediaKeys<ResponseObjectMap<PathMethod>>>;
312
- /** Return JSON-like 1XX, 3XX, 4XX, 5XX and `default` responses from a path + HTTP method */
313
- type ErrorResponseJSON<PathMethod extends Record<string | number, any>> = ErrorResponse<ResponseObjectMap<PathMethod>, JSONMediaKeys<ResponseObjectMap<PathMethod>>>;
314
- /**
315
- * The media types of the responses `T` that may hold JSON (`IsJSONMediaType`), for the JSON
316
- * helpers to pick by: their keys, as `JSONMediaType` cannot leave out a `json` in parameters. A
317
- * content map with an index signature has no such key, so it gives `JSONMediaType`, which picks
318
- * the schema of its signature.
310
+ /**
311
+ * Return first JSON-like 2XX response from a path + HTTP method; for a union of operations, the
312
+ * union of each one's.
313
+ */
314
+ type SuccessResponseJSON<PathMethod extends Record<string | number, any>> = PathMethod extends unknown ? SuccessResponse<ResponseObjectMap<PathMethod>, JSONMediaKeys<ResponseObjectMap<PathMethod>>> : never;
315
+ /**
316
+ * Return JSON-like 1XX, 3XX, 4XX, 5XX and `default` responses from a path + HTTP method; for a
317
+ * union of operations, the union of each one's.
318
+ */
319
+ type ErrorResponseJSON<PathMethod extends Record<string | number, any>> = PathMethod extends unknown ? ErrorResponse<ResponseObjectMap<PathMethod>, JSONMediaKeys<ResponseObjectMap<PathMethod>>> : never;
320
+ /**
321
+ * The media types of the responses `T` (of one operation) that may hold JSON (`IsJSONMediaType`),
322
+ * for the JSON helpers to pick by: their keys, as `JSONMediaType` cannot leave out a `json` in
323
+ * parameters. A content map with an index signature has no such key, so it gives
324
+ * `JSONMediaType`, which picks the schema of its signature. The helpers pick per operation: the
325
+ * keys of a union of response maps are only the status codes they share, so the media types of
326
+ * the other statuses were lost, and the media types of one operation could pick in another.
319
327
  */
320
328
  type JSONMediaKeys<T> = {
321
329
  [Status in keyof T]: T[Status] extends {
@@ -307,15 +307,23 @@ type JSONMediaType = JSONMediaPattern | JSONMediaRange;
307
307
  * parameters, which do not count.
308
308
  */
309
309
  type IsJSONMediaType<Key> = Key extends string ? IsJSONMediaPattern<Key> extends true ? true : MediaSubtype<Lowercase<Key>> extends "*" ? true : false : false;
310
- /** Return first JSON-like 2XX response from a path + HTTP method */
311
- type SuccessResponseJSON<PathMethod extends Record<string | number, any>> = SuccessResponse<ResponseObjectMap<PathMethod>, JSONMediaKeys<ResponseObjectMap<PathMethod>>>;
312
- /** Return JSON-like 1XX, 3XX, 4XX, 5XX and `default` responses from a path + HTTP method */
313
- type ErrorResponseJSON<PathMethod extends Record<string | number, any>> = ErrorResponse<ResponseObjectMap<PathMethod>, JSONMediaKeys<ResponseObjectMap<PathMethod>>>;
314
- /**
315
- * The media types of the responses `T` that may hold JSON (`IsJSONMediaType`), for the JSON
316
- * helpers to pick by: their keys, as `JSONMediaType` cannot leave out a `json` in parameters. A
317
- * content map with an index signature has no such key, so it gives `JSONMediaType`, which picks
318
- * the schema of its signature.
310
+ /**
311
+ * Return first JSON-like 2XX response from a path + HTTP method; for a union of operations, the
312
+ * union of each one's.
313
+ */
314
+ type SuccessResponseJSON<PathMethod extends Record<string | number, any>> = PathMethod extends unknown ? SuccessResponse<ResponseObjectMap<PathMethod>, JSONMediaKeys<ResponseObjectMap<PathMethod>>> : never;
315
+ /**
316
+ * Return JSON-like 1XX, 3XX, 4XX, 5XX and `default` responses from a path + HTTP method; for a
317
+ * union of operations, the union of each one's.
318
+ */
319
+ type ErrorResponseJSON<PathMethod extends Record<string | number, any>> = PathMethod extends unknown ? ErrorResponse<ResponseObjectMap<PathMethod>, JSONMediaKeys<ResponseObjectMap<PathMethod>>> : never;
320
+ /**
321
+ * The media types of the responses `T` (of one operation) that may hold JSON (`IsJSONMediaType`),
322
+ * for the JSON helpers to pick by: their keys, as `JSONMediaType` cannot leave out a `json` in
323
+ * parameters. A content map with an index signature has no such key, so it gives
324
+ * `JSONMediaType`, which picks the schema of its signature. The helpers pick per operation: the
325
+ * keys of a union of response maps are only the status codes they share, so the media types of
326
+ * the other statuses were lost, and the media types of one operation could pick in another.
319
327
  */
320
328
  type JSONMediaKeys<T> = {
321
329
  [Status in keyof T]: T[Status] extends {
package/dist/helpers.d.ts CHANGED
@@ -307,15 +307,23 @@ type JSONMediaType = JSONMediaPattern | JSONMediaRange;
307
307
  * parameters, which do not count.
308
308
  */
309
309
  type IsJSONMediaType<Key> = Key extends string ? IsJSONMediaPattern<Key> extends true ? true : MediaSubtype<Lowercase<Key>> extends "*" ? true : false : false;
310
- /** Return first JSON-like 2XX response from a path + HTTP method */
311
- type SuccessResponseJSON<PathMethod extends Record<string | number, any>> = SuccessResponse<ResponseObjectMap<PathMethod>, JSONMediaKeys<ResponseObjectMap<PathMethod>>>;
312
- /** Return JSON-like 1XX, 3XX, 4XX, 5XX and `default` responses from a path + HTTP method */
313
- type ErrorResponseJSON<PathMethod extends Record<string | number, any>> = ErrorResponse<ResponseObjectMap<PathMethod>, JSONMediaKeys<ResponseObjectMap<PathMethod>>>;
314
- /**
315
- * The media types of the responses `T` that may hold JSON (`IsJSONMediaType`), for the JSON
316
- * helpers to pick by: their keys, as `JSONMediaType` cannot leave out a `json` in parameters. A
317
- * content map with an index signature has no such key, so it gives `JSONMediaType`, which picks
318
- * the schema of its signature.
310
+ /**
311
+ * Return first JSON-like 2XX response from a path + HTTP method; for a union of operations, the
312
+ * union of each one's.
313
+ */
314
+ type SuccessResponseJSON<PathMethod extends Record<string | number, any>> = PathMethod extends unknown ? SuccessResponse<ResponseObjectMap<PathMethod>, JSONMediaKeys<ResponseObjectMap<PathMethod>>> : never;
315
+ /**
316
+ * Return JSON-like 1XX, 3XX, 4XX, 5XX and `default` responses from a path + HTTP method; for a
317
+ * union of operations, the union of each one's.
318
+ */
319
+ type ErrorResponseJSON<PathMethod extends Record<string | number, any>> = PathMethod extends unknown ? ErrorResponse<ResponseObjectMap<PathMethod>, JSONMediaKeys<ResponseObjectMap<PathMethod>>> : never;
320
+ /**
321
+ * The media types of the responses `T` (of one operation) that may hold JSON (`IsJSONMediaType`),
322
+ * for the JSON helpers to pick by: their keys, as `JSONMediaType` cannot leave out a `json` in
323
+ * parameters. A content map with an index signature has no such key, so it gives
324
+ * `JSONMediaType`, which picks the schema of its signature. The helpers pick per operation: the
325
+ * keys of a union of response maps are only the status codes they share, so the media types of
326
+ * the other statuses were lost, and the media types of one operation could pick in another.
319
327
  */
320
328
  type JSONMediaKeys<T> = {
321
329
  [Status in keyof T]: T[Status] extends {
package/dist/index.d.cts CHANGED
@@ -133,13 +133,26 @@ type ParseAs = keyof BodyType;
133
133
  * its body, and `undefined` or a left-out `parseAs` is the default `"json"`, as at runtime: a
134
134
  * wrapper that passes on `parseAs?: "text"` gets `string | T`, not `T` only. Options without
135
135
  * `parseAs`, or whose `parseAs` may be any value (the declared init type, as for a call without
136
- * options), give `T`, as in openapi-fetch. No `infer`: TypeScript relates a type to a deferred
137
- * conditional type through both of its branches only when it infers nothing, and generic hooks
138
- * return the data of a call as this type.
136
+ * options), give `T`, as in openapi-fetch; each member of a union of options gives its own data.
137
+ * No `infer`: TypeScript relates a type to a deferred conditional type through both of its
138
+ * branches only when it infers nothing, and generic hooks return the data of a call as this type.
139
+ * It distributes over `Options`, as openapi-fetch's does, so the options of a generic call (a
140
+ * wrapper's `FetchOptions` of a generic path with `parseAs: "text"`) give the data of their
141
+ * constraint: TypeScript reads a deferred distributive type through its check type's constraint.
139
142
  */
140
- type ParseAsResponse<T, Options> = [MissingParseAsValues<Options>] extends [never]
141
- ? T
142
- : BodyType<T>[ParseAsValue<ParseAsValues<Options>>];
143
+ type ParseAsResponse<T, Options> = Options extends unknown
144
+ ? BodyType<T>[ParseAsKey<Options>]
145
+ : never;
146
+
147
+ /**
148
+ * The key of `BodyType` that the options `Options` read the body with. A conditional type of its
149
+ * own, inside the index: one in the branch of `ParseAsResponse` that picked `T` would be read
150
+ * through both of its branches while TypeScript reads the constraint above, as `never` fits any
151
+ * check type, so a generic `parseAs: "text"` gave the JSON body too.
152
+ */
153
+ type ParseAsKey<Options> = [MissingParseAsValues<Options>] extends [never]
154
+ ? "json"
155
+ : ParseAsValue<ParseAsValues<Options>>;
143
156
 
144
157
  /**
145
158
  * The `parseAs` values that `Options` may have; `undefined` when it may be left out. One
@@ -160,8 +173,8 @@ type ParseAsValues<Options> = Options extends unknown
160
173
  : never;
161
174
 
162
175
  /**
163
- * The `parseAs` values that `Options` cannot have, as `ParseAsValues` reads them. It does not
164
- * distribute: a union of options cannot have a value only when none of its members can.
176
+ * The `parseAs` values that the options `Options` (one member of a union) cannot have, as
177
+ * `ParseAsValues` reads them.
165
178
  */
166
179
  type MissingParseAsValues<Options> =
167
180
  | ([Options] extends [RequiredParseAs] ? undefined : never)
package/dist/index.d.mts CHANGED
@@ -133,13 +133,26 @@ type ParseAs = keyof BodyType;
133
133
  * its body, and `undefined` or a left-out `parseAs` is the default `"json"`, as at runtime: a
134
134
  * wrapper that passes on `parseAs?: "text"` gets `string | T`, not `T` only. Options without
135
135
  * `parseAs`, or whose `parseAs` may be any value (the declared init type, as for a call without
136
- * options), give `T`, as in openapi-fetch. No `infer`: TypeScript relates a type to a deferred
137
- * conditional type through both of its branches only when it infers nothing, and generic hooks
138
- * return the data of a call as this type.
136
+ * options), give `T`, as in openapi-fetch; each member of a union of options gives its own data.
137
+ * No `infer`: TypeScript relates a type to a deferred conditional type through both of its
138
+ * branches only when it infers nothing, and generic hooks return the data of a call as this type.
139
+ * It distributes over `Options`, as openapi-fetch's does, so the options of a generic call (a
140
+ * wrapper's `FetchOptions` of a generic path with `parseAs: "text"`) give the data of their
141
+ * constraint: TypeScript reads a deferred distributive type through its check type's constraint.
139
142
  */
140
- type ParseAsResponse<T, Options> = [MissingParseAsValues<Options>] extends [never]
141
- ? T
142
- : BodyType<T>[ParseAsValue<ParseAsValues<Options>>];
143
+ type ParseAsResponse<T, Options> = Options extends unknown
144
+ ? BodyType<T>[ParseAsKey<Options>]
145
+ : never;
146
+
147
+ /**
148
+ * The key of `BodyType` that the options `Options` read the body with. A conditional type of its
149
+ * own, inside the index: one in the branch of `ParseAsResponse` that picked `T` would be read
150
+ * through both of its branches while TypeScript reads the constraint above, as `never` fits any
151
+ * check type, so a generic `parseAs: "text"` gave the JSON body too.
152
+ */
153
+ type ParseAsKey<Options> = [MissingParseAsValues<Options>] extends [never]
154
+ ? "json"
155
+ : ParseAsValue<ParseAsValues<Options>>;
143
156
 
144
157
  /**
145
158
  * The `parseAs` values that `Options` may have; `undefined` when it may be left out. One
@@ -160,8 +173,8 @@ type ParseAsValues<Options> = Options extends unknown
160
173
  : never;
161
174
 
162
175
  /**
163
- * The `parseAs` values that `Options` cannot have, as `ParseAsValues` reads them. It does not
164
- * distribute: a union of options cannot have a value only when none of its members can.
176
+ * The `parseAs` values that the options `Options` (one member of a union) cannot have, as
177
+ * `ParseAsValues` reads them.
165
178
  */
166
179
  type MissingParseAsValues<Options> =
167
180
  | ([Options] extends [RequiredParseAs] ? undefined : never)
package/dist/index.d.ts CHANGED
@@ -133,13 +133,26 @@ type ParseAs = keyof BodyType;
133
133
  * its body, and `undefined` or a left-out `parseAs` is the default `"json"`, as at runtime: a
134
134
  * wrapper that passes on `parseAs?: "text"` gets `string | T`, not `T` only. Options without
135
135
  * `parseAs`, or whose `parseAs` may be any value (the declared init type, as for a call without
136
- * options), give `T`, as in openapi-fetch. No `infer`: TypeScript relates a type to a deferred
137
- * conditional type through both of its branches only when it infers nothing, and generic hooks
138
- * return the data of a call as this type.
136
+ * options), give `T`, as in openapi-fetch; each member of a union of options gives its own data.
137
+ * No `infer`: TypeScript relates a type to a deferred conditional type through both of its
138
+ * branches only when it infers nothing, and generic hooks return the data of a call as this type.
139
+ * It distributes over `Options`, as openapi-fetch's does, so the options of a generic call (a
140
+ * wrapper's `FetchOptions` of a generic path with `parseAs: "text"`) give the data of their
141
+ * constraint: TypeScript reads a deferred distributive type through its check type's constraint.
139
142
  */
140
- type ParseAsResponse<T, Options> = [MissingParseAsValues<Options>] extends [never]
141
- ? T
142
- : BodyType<T>[ParseAsValue<ParseAsValues<Options>>];
143
+ type ParseAsResponse<T, Options> = Options extends unknown
144
+ ? BodyType<T>[ParseAsKey<Options>]
145
+ : never;
146
+
147
+ /**
148
+ * The key of `BodyType` that the options `Options` read the body with. A conditional type of its
149
+ * own, inside the index: one in the branch of `ParseAsResponse` that picked `T` would be read
150
+ * through both of its branches while TypeScript reads the constraint above, as `never` fits any
151
+ * check type, so a generic `parseAs: "text"` gave the JSON body too.
152
+ */
153
+ type ParseAsKey<Options> = [MissingParseAsValues<Options>] extends [never]
154
+ ? "json"
155
+ : ParseAsValue<ParseAsValues<Options>>;
143
156
 
144
157
  /**
145
158
  * The `parseAs` values that `Options` may have; `undefined` when it may be left out. One
@@ -160,8 +173,8 @@ type ParseAsValues<Options> = Options extends unknown
160
173
  : never;
161
174
 
162
175
  /**
163
- * The `parseAs` values that `Options` cannot have, as `ParseAsValues` reads them. It does not
164
- * distribute: a union of options cannot have a value only when none of its members can.
176
+ * The `parseAs` values that the options `Options` (one member of a union) cannot have, as
177
+ * `ParseAsValues` reads them.
165
178
  */
166
179
  type MissingParseAsValues<Options> =
167
180
  | ([Options] extends [RequiredParseAs] ? undefined : never)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "openapi-typesafe-fetch",
3
3
  "description": "Fast, type-safe fetch client for your OpenAPI schema. About 10.5 kB minified, 4 kB gzipped. Works with React, Vue, Svelte, or vanilla JS.",
4
- "version": "1.0.0-rc.11",
4
+ "version": "1.0.0-rc.12",
5
5
  "author": {
6
6
  "name": "Fedor Chishchin",
7
7
  "url": "https://github.com/fedorello"
@@ -67,7 +67,7 @@
67
67
  "express": "5.3.0",
68
68
  "feature-fetch": "0.1.2",
69
69
  "node-forge": "1.4.3",
70
- "openapi-typesafe": "^1.0.0-rc.11",
70
+ "openapi-typesafe": "^1.0.0-rc.12",
71
71
  "openapi-typescript-fetch": "2.2.1",
72
72
  "typescript": "^6.0.3",
73
73
  "undici": "7.30.2",
package/src/helpers.ts CHANGED
@@ -454,25 +454,33 @@ type IsJSONMediaType<Key> = Key extends string
454
454
  : false
455
455
  : false;
456
456
 
457
- /** Return first JSON-like 2XX response from a path + HTTP method */
457
+ /**
458
+ * Return first JSON-like 2XX response from a path + HTTP method; for a union of operations, the
459
+ * union of each one's.
460
+ */
458
461
  // biome-ignore lint/suspicious/noExplicitAny: unknown rejects the generated interfaces
459
- export type SuccessResponseJSON<PathMethod extends Record<string | number, any>> = SuccessResponse<
460
- ResponseObjectMap<PathMethod>,
461
- JSONMediaKeys<ResponseObjectMap<PathMethod>>
462
- >;
462
+ export type SuccessResponseJSON<PathMethod extends Record<string | number, any>> =
463
+ PathMethod extends unknown
464
+ ? SuccessResponse<ResponseObjectMap<PathMethod>, JSONMediaKeys<ResponseObjectMap<PathMethod>>>
465
+ : never;
463
466
 
464
- /** Return JSON-like 1XX, 3XX, 4XX, 5XX and `default` responses from a path + HTTP method */
467
+ /**
468
+ * Return JSON-like 1XX, 3XX, 4XX, 5XX and `default` responses from a path + HTTP method; for a
469
+ * union of operations, the union of each one's.
470
+ */
465
471
  // biome-ignore lint/suspicious/noExplicitAny: unknown rejects the generated interfaces
466
- export type ErrorResponseJSON<PathMethod extends Record<string | number, any>> = ErrorResponse<
467
- ResponseObjectMap<PathMethod>,
468
- JSONMediaKeys<ResponseObjectMap<PathMethod>>
469
- >;
472
+ export type ErrorResponseJSON<PathMethod extends Record<string | number, any>> =
473
+ PathMethod extends unknown
474
+ ? ErrorResponse<ResponseObjectMap<PathMethod>, JSONMediaKeys<ResponseObjectMap<PathMethod>>>
475
+ : never;
470
476
 
471
477
  /**
472
- * The media types of the responses `T` that may hold JSON (`IsJSONMediaType`), for the JSON
473
- * helpers to pick by: their keys, as `JSONMediaType` cannot leave out a `json` in parameters. A
474
- * content map with an index signature has no such key, so it gives `JSONMediaType`, which picks
475
- * the schema of its signature.
478
+ * The media types of the responses `T` (of one operation) that may hold JSON (`IsJSONMediaType`),
479
+ * for the JSON helpers to pick by: their keys, as `JSONMediaType` cannot leave out a `json` in
480
+ * parameters. A content map with an index signature has no such key, so it gives
481
+ * `JSONMediaType`, which picks the schema of its signature. The helpers pick per operation: the
482
+ * keys of a union of response maps are only the status codes they share, so the media types of
483
+ * the other statuses were lost, and the media types of one operation could pick in another.
476
484
  */
477
485
  type JSONMediaKeys<T> = {
478
486
  [Status in keyof T]: T[Status] extends { content: infer Content }
package/src/index.d.ts CHANGED
@@ -143,13 +143,26 @@ export type ParseAs = keyof BodyType;
143
143
  * its body, and `undefined` or a left-out `parseAs` is the default `"json"`, as at runtime: a
144
144
  * wrapper that passes on `parseAs?: "text"` gets `string | T`, not `T` only. Options without
145
145
  * `parseAs`, or whose `parseAs` may be any value (the declared init type, as for a call without
146
- * options), give `T`, as in openapi-fetch. No `infer`: TypeScript relates a type to a deferred
147
- * conditional type through both of its branches only when it infers nothing, and generic hooks
148
- * return the data of a call as this type.
146
+ * options), give `T`, as in openapi-fetch; each member of a union of options gives its own data.
147
+ * No `infer`: TypeScript relates a type to a deferred conditional type through both of its
148
+ * branches only when it infers nothing, and generic hooks return the data of a call as this type.
149
+ * It distributes over `Options`, as openapi-fetch's does, so the options of a generic call (a
150
+ * wrapper's `FetchOptions` of a generic path with `parseAs: "text"`) give the data of their
151
+ * constraint: TypeScript reads a deferred distributive type through its check type's constraint.
149
152
  */
150
- export type ParseAsResponse<T, Options> = [MissingParseAsValues<Options>] extends [never]
151
- ? T
152
- : BodyType<T>[ParseAsValue<ParseAsValues<Options>>];
153
+ export type ParseAsResponse<T, Options> = Options extends unknown
154
+ ? BodyType<T>[ParseAsKey<Options>]
155
+ : never;
156
+
157
+ /**
158
+ * The key of `BodyType` that the options `Options` read the body with. A conditional type of its
159
+ * own, inside the index: one in the branch of `ParseAsResponse` that picked `T` would be read
160
+ * through both of its branches while TypeScript reads the constraint above, as `never` fits any
161
+ * check type, so a generic `parseAs: "text"` gave the JSON body too.
162
+ */
163
+ type ParseAsKey<Options> = [MissingParseAsValues<Options>] extends [never]
164
+ ? "json"
165
+ : ParseAsValue<ParseAsValues<Options>>;
153
166
 
154
167
  /**
155
168
  * The `parseAs` values that `Options` may have; `undefined` when it may be left out. One
@@ -170,8 +183,8 @@ type ParseAsValues<Options> = Options extends unknown
170
183
  : never;
171
184
 
172
185
  /**
173
- * The `parseAs` values that `Options` cannot have, as `ParseAsValues` reads them. It does not
174
- * distribute: a union of options cannot have a value only when none of its members can.
186
+ * The `parseAs` values that the options `Options` (one member of a union) cannot have, as
187
+ * `ParseAsValues` reads them.
175
188
  */
176
189
  type MissingParseAsValues<Options> =
177
190
  | ([Options] extends [RequiredParseAs] ? undefined : never)