Skip to content

fix(openapi-typescript-helpers): preserve tuple types in Readable/Writable#2673

Open
panwauu wants to merge 2 commits intoopenapi-ts:mainfrom
panwauu:fix/readable-writetable-preserve-tuple-types
Open

fix(openapi-typescript-helpers): preserve tuple types in Readable/Writable#2673
panwauu wants to merge 2 commits intoopenapi-ts:mainfrom
panwauu:fix/readable-writetable-preserve-tuple-types

Conversation

@panwauu
Copy link

@panwauu panwauu commented Mar 12, 2026

Changes

Fixes #2632Readable<T> and Writable<T> in openapi-typescript-helpers collapse tuple types (e.g. [string, string][] becomes string[][]).

The array branch T extends (infer E)[] ? Readable<E>[] matches tuples since tuples extend arrays, but infer E extracts the union of all element types, losing positional information. This affects all responses in openapi-fetch 0.17.0 because Readable<T> is applied unconditionally in FetchResponse — even when --read-write-markers is not enabled.

Replaced with T extends readonly any[] ? { [K in keyof T]: Readable<T[K]> } which uses TypeScript's mapped type special-casing for tuples to preserve tuple structure. Applied the same fix to Writable<T>.

Before:

Readable<[string, string][]>  →  string[][]

After:

Readable<[string, string][]>  →  [string, string][]

How to Review

The change is in packages/openapi-typescript-helpers/src/index.ts — one line each in Readable<T> and Writable<T>.

I was not able to create a adequate test due to limited experience with typescript generics and no experience in the repo itself. I could only verify very basically by adding a line after the Readable definition:

type test = Readable<[string, string]>

The type for test should now be [string, string] where it was string[] before

Checklist

  • Unit tests updated
  • docs/ updated (if necessary)
  • pnpm run update:examples run (only applicable for openapi-typescript)

@panwauu panwauu requested a review from a team as a code owner March 12, 2026 10:55
@panwauu panwauu requested a review from gzm0 March 12, 2026 10:55
@netlify
Copy link

netlify bot commented Mar 12, 2026

👷 Deploy request for openapi-ts pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit ad696ac

@changeset-bot
Copy link

changeset-bot bot commented Mar 12, 2026

🦋 Changeset detected

Latest commit: ad696ac

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
openapi-typescript-helpers Patch
openapi-fetch Patch
openapi-react-query Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Contributor

@gzm0 gzm0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Implementation looks good. Just one optional comment that might allow simplification.

Could you add some tests for this? I think either of the following would probably work:

  • Add to read-write-test.ts: fast but not super clean.
  • Create tests for openapi-typescript-helpers: nicer, but a bit more work.

? Readable<E>[]
: T extends readonly any[]
? { [K in keyof T]: Readable<T[K]> }
: T extends object
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
: T extends object
: T extends object | readonly any[]

Would that work as well? Then we could have one less branch (same below).

IIUC the mapped type for object "just" recursively resolved $Read / $Write in keys, that behavior doesn't bother us.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Behavior change in 0.17.0 for array and prefixItems

2 participants