Skip to content

feat: add TypeScript 6 support#2774

Open
benjamineckstein wants to merge 2 commits intoopenapi-ts:mainfrom
benjamineckstein:feat/typescript-6-support
Open

feat: add TypeScript 6 support#2774
benjamineckstein wants to merge 2 commits intoopenapi-ts:mainfrom
benjamineckstein:feat/typescript-6-support

Conversation

@benjamineckstein
Copy link
Copy Markdown

@benjamineckstein benjamineckstein commented Apr 15, 2026

Summary

Add full TypeScript 6 support — not just the peer dep range, but also a fix for a TS6 behavioral change that breaks Readable<T> and Writable<T>.

Changes

Peer dep & devDependency (commit 1):

  • packages/openapi-typescript/package.json: widen peer dep ^5.x^5.x || ^6.x
  • packages/openapi-typescript-helpers/package.json: upgrade devDependency 5.9.36.0.2

Fix Readable/Writable types (commit 2):
In TypeScript 6, Date extends object evaluates to true (changed from TS5). This caused Readable<T> and Writable<T> to structurally expand built-in objects like Date into { toString: {}; toDateString: {}; ... } instead of preserving the Date type.

Added a guard clause for Date | RegExp | ((...args: never[]) => unknown) before the T extends object branch in both type utilities, preserving built-in objects. This fix is backward compatible with TS5.

Changeset: patch release for both openapi-typescript and openapi-typescript-helpers

Validation

  • pnpm run build — all 4 packages build successfully
  • pnpm test — all 7 test suites pass
  • pnpm run lint — clean

Context

- Widen peer dep: `^5.x` → `^5.x || ^6.x`
- Upgrade devDependency in openapi-typescript-helpers: 5.9.3 → 6.0.2
- Build, tests, and lint all pass with TS6
- No code changes needed

Closes openapi-ts#2723
@benjamineckstein benjamineckstein requested a review from a team as a code owner April 15, 2026 08:44
@benjamineckstein benjamineckstein requested a review from drwpow April 15, 2026 08:44
@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 15, 2026

👷 Deploy request for openapi-ts pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit a749a52

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 15, 2026

🦋 Changeset detected

Latest commit: a749a52

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

This PR includes changesets to release 4 packages
Name Type
openapi-typescript Patch
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

…e/Writable types for TS6

In TypeScript 6, `Date extends object` evaluates to `true` (changed from
TS5). This caused `Readable<T>` and `Writable<T>` to structurally expand
Date, RegExp, and function fields instead of preserving them.

Add a guard clause for built-in objects (Date, RegExp, functions) before
the `T extends object` branch in both type utilities.

Ref: openapi-ts#2723
@benjamineckstein benjamineckstein changed the title feat(openapi-typescript): add TypeScript 6 support feat: add TypeScript 6 support Apr 15, 2026
: T extends object
? { [K in keyof T as NonNullable<T[K]> extends $Write<any> ? never : K]: Readable<T[K]> }
: T;
: T extends Date | RegExp | ((...args: never[]) => unknown)
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

In TypeScript 6, Date extends object now evaluates to true (it was false in TS5). Without this guard, Readable<T> would structurally expand Date fields into { toString: {}; toDateString: {}; ... } instead of preserving the Date type — making any schema containing Date fields incompatible with itself when accessed through FetchResponse.

This guard preserves built-in objects (Date, RegExp, functions) by matching them before the generic T extends object branch. It's backward compatible with TS5 since these types were never matched by T extends object there.

jeremy added a commit to basecamp/fizzy-sdk that referenced this pull request Apr 16, 2026
The Dependabot group update bumped typescript to ^6.0.2, but
openapi-typescript@7.13.0 still declares peer typescript ^5.x, so
npm ci fails to resolve. Revert just the typescript bump (keep the
other five: @types/node, @vitest/coverage-v8, msw, oxlint, vitest)
and regenerate the lockfile against 5.9.3.

Add a temporary dependabot.yml ignore on typescript semver-major
bumps so the same mismatch doesn't keep getting proposed. Remove
the ignore once openapi-typescript ships TS 6 support
(openapi-ts/openapi-typescript#2774).
jeremy added a commit to basecamp/fizzy-sdk that referenced this pull request Apr 19, 2026
* Bump the npm-deps group across 1 directory with 6 updates

Bumps the npm-deps group with 5 updates in the /typescript directory:

| Package | From | To |
| --- | --- | --- |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `25.5.0` | `25.5.2` |
| [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) | `4.1.0` | `4.1.2` |
| [msw](https://github.com/mswjs/msw) | `2.12.14` | `2.13.0` |
| [oxlint](https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint) | `1.56.0` | `1.58.0` |
| [typescript](https://github.com/microsoft/TypeScript) | `5.9.3` | `6.0.2` |



Updates `@types/node` from 25.5.0 to 25.5.2
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@vitest/coverage-v8` from 4.1.0 to 4.1.2
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.2/packages/coverage-v8)

Updates `msw` from 2.12.14 to 2.13.0
- [Release notes](https://github.com/mswjs/msw/releases)
- [Changelog](https://github.com/mswjs/msw/blob/main/CHANGELOG.md)
- [Commits](mswjs/msw@v2.12.14...v2.13.0)

Updates `oxlint` from 1.56.0 to 1.58.0
- [Release notes](https://github.com/oxc-project/oxc/releases)
- [Changelog](https://github.com/oxc-project/oxc/blob/main/npm/oxlint/CHANGELOG.md)
- [Commits](https://github.com/oxc-project/oxc/commits/oxlint_v1.58.0/npm/oxlint)

Updates `typescript` from 5.9.3 to 6.0.2
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Commits](microsoft/TypeScript@v5.9.3...v6.0.2)

Updates `vitest` from 4.1.0 to 4.1.2
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.2/packages/vitest)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 25.5.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-deps
- dependency-name: "@vitest/coverage-v8"
  dependency-version: 4.1.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-deps
- dependency-name: msw
  dependency-version: 2.13.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: oxlint
  dependency-version: 1.58.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: typescript
  dependency-version: 6.0.2
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: vitest
  dependency-version: 4.1.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-deps
...

Signed-off-by: dependabot[bot] <support@github.com>

* Keep typescript on 5.9.x until openapi-typescript supports TS 6

The Dependabot group update bumped typescript to ^6.0.2, but
openapi-typescript@7.13.0 still declares peer typescript ^5.x, so
npm ci fails to resolve. Revert just the typescript bump (keep the
other five: @types/node, @vitest/coverage-v8, msw, oxlint, vitest)
and regenerate the lockfile against 5.9.3.

Add a temporary dependabot.yml ignore on typescript semver-major
bumps so the same mismatch doesn't keep getting proposed. Remove
the ignore once openapi-typescript ships TS 6 support
(openapi-ts/openapi-typescript#2774).

* Raise engines.node floor to >=20 (drop EOL Node 18)

Node 18 reached end-of-life on 2025-04-30. Currently supported Node
releases are 20 (Maintenance LTS until 2026-04-30), 22 (LTS), and 24.
Lift the consumer-facing engines floor accordingly.

Dev toolchain (oxlint, @inquirer/*, etc.) already requires Node 20.x
or newer at the transitive level — that's fine for contributors and
separate from the published SDK's runtime contract.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Daer <jeremy@37signals.com>
jackmusick added a commit to jackmusick/bifrost that referenced this pull request Apr 25, 2026
…tream (#73)

## Summary
- eslint 10 + matched plugins: blocked on react-hooks 7.x's expanded
recommended preset surfacing ~60 real lint errors. Need a code-fix sweep
first.
- typescript 6: blocked on openapi-typescript widening its peer dep to
TS 6 ([upstream PR
#2774](openapi-ts/openapi-typescript#2774)).

Adds ignore rules so Dependabot stops opening unmergeable PRs for these
majors. Closing #61 and #65 in tandem.

## Test plan
- [ ] CI green on this PR (lint/typecheck/tests don't depend on
Dependabot config)
- [ ] Verify Dependabot won't re-open the bumps next Monday

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@benjamineckstein
Copy link
Copy Markdown
Author

What is missing to merge this PR? ... now it contains merge conflicts ...

denisvmedia added a commit to denisvmedia/inventario that referenced this pull request Apr 29, 2026
The .npmrc workaround is metadata-only — npm ls confirms typescript@6.0.3
is the only version installed. Add a TODO link to openapi-ts/openapi-typescript#2774
so it's clear when the flag can come off.
denisvmedia added a commit to denisvmedia/inventario that referenced this pull request Apr 29, 2026
…degen (#1428)

* [#1403] Frontend-react data layer: HTTP client + TanStack Query + OpenAPI codegen

HTTP wrapper at src/lib/http.ts handles bearer + CSRF, /api/v1/<resource>
to /api/v1/g/{slug}/<resource> rewriting, single-flight refresh on 401,
and surfaces non-2xx as HttpError so React Query can react via onError.
Storage keys (inventario_token, inventario_csrf_token, inventario_user)
match the legacy Vue frontend so a session survives the dual-bundle
INVENTARIO_FRONTEND switch (#1401).

QueryClient defaults: staleTime 30s, retry 1 (skipped for 4xx).
Providers wraps QueryClientProvider + ReactQueryDevtools (dev only) +
ThemeProvider; main.tsx uses it.

OpenAPI codegen converts go/docs/swagger.json (Swagger 2.0) to OAS3 via
swagger2openapi, then emits src/types/api.d.ts via openapi-typescript.
Exposed as npm run codegen / codegen:check, make codegen-frontend-react
/ codegen-frontend-react-check, and a new frontend-react-codegen
workflow that fails the build on drift.

Sample feature slice at features/session/ proves the layer end-to-end:
useCurrentUser query and an optimistic useLogout mutation with cache
rollback on error.

Tests: 40 (Vitest + MSW v2) covering each prefix rewrite, /auth/*
pass-through, slug encoding, CSRF only on mutations + rotation from
response headers, AbortSignal forwarding, 4xx/5xx HttpError, the full
refresh+retry path, refresh-failure clear+navigate, background
/auth/me 401 non-redirect, and single-flight refresh dedup.

.npmrc pins legacy-peer-deps=true because openapi-typescript@7 declares
peer typescript@^5.x while the scaffold is on TS 6 — the peer is
build-time only and emit goes through openapi-typescript's bundled
compiler, so the mismatch is benign. Drop the flag once
openapi-typescript ships TS 6 support.

Closes #1403.

* [#1403] Document legacy-peer-deps workaround with upstream PR link

The .npmrc workaround is metadata-only — npm ls confirms typescript@6.0.3
is the only version installed. Add a TODO link to openapi-ts/openapi-typescript#2774
so it's clear when the flag can come off.

* [#1403] Address CI failures + Copilot review

- Dockerfile: copy frontend-react/.npmrc into the React builder stage so
  npm ci picks up legacy-peer-deps=true (Build linux/{amd64,arm64} fix).
- ApiResponse helper: try application/vnd.api+json first then fall back
  to application/json, and accept any 2xx status. Most Inventario
  endpoints serve JSON:API, so the previous 'application/json'-only
  shape resolved to never for them.
- useLogout: removeQueries() instead of setQueryData(..., null) so the
  cache stays type-true to the query's CurrentUser shape; consumers see
  data === undefined rather than a surprise null at runtime.
- Drop the meCalls > 1 assertion in the optimistic-logout test — it
  encoded an implementation detail (invalidate-after-remove timing) that
  did not survive the removeQueries switch. New assertion pins the real
  invariant: cache stays cleared after a successful logout.
- Prettier: re-format http.ts, http.test.ts, types/index.ts, generated
  api.d.ts, and the session test (Lint Frontend (React) job fix).

* [#1403] Exclude generated api.d.ts from prettier

The previous commit's prettier sweep reformatted src/types/api.d.ts,
which then disagreed with what scripts/codegen.mjs produces — the
codegen-drift CI job rejected the result.

Add .prettierignore to keep the generator's emit untouched, and
restore api.d.ts to the codegen-true output.
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.

Add support for TypeScript 6

1 participant