Repository navigation
fix(types): Fix TS 4.x legacy types with skipLibCheck off; internal(ci): fail-open esmodule relevance, faster rest legacy types - #4122
Conversation
🦋 Changeset detectedLatest commit: 479badb The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 packages
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 |
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
|
Size Change: 0 B Total Size: 103 kB ℹ️ View Unchanged
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #4122 +/- ##
=======================================
Coverage 97.88% 97.88%
=======================================
Files 158 158
Lines 3079 3079
Branches 616 616
=======================================
Hits 3014 3014
Misses 18 18
Partials 47 47 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Benchmark React
Details
| Benchmark suite | Current: 479badb | Previous: 8b3bb89 | Ratio |
|---|---|---|---|
data-client: getlist-100 |
204.08 ops/s (± 4.7%) |
175.44 ops/s (± 5.1%) |
0.86 |
data-client: getlist-500 |
63.69 ops/s (± 4.5%) |
52.22 ops/s (± 3.4%) |
0.82 |
data-client: update-entity |
500 ops/s (± 9.9%) |
416.67 ops/s (± 5.6%) |
0.83 |
data-client: update-user |
434.78 ops/s (± 6.6%) |
370.37 ops/s (± 7.6%) |
0.85 |
data-client: getlist-500-sorted |
63.1 ops/s (± 10.0%) |
55.26 ops/s (± 6.2%) |
0.88 |
data-client: update-entity-sorted |
476.19 ops/s (± 10.2%) |
322.58 ops/s (± 6.0%) |
0.68 |
data-client: update-entity-multi-view |
488.1 ops/s (± 8.8%) |
339.08 ops/s (± 5.7%) |
0.69 |
data-client: list-detail-switch-10 |
20.2 ops/s (± 9.0%) |
12.58 ops/s (± 8.4%) |
0.62 |
data-client: update-user-10000 |
113 ops/s (± 13.8%) |
79.68 ops/s (± 10.4%) |
0.71 |
data-client: invalidate-and-resolve |
55.1 ops/s (± 5.3%) |
46.73 ops/s (± 6.7%) |
0.85 |
data-client: unshift-item |
294.12 ops/s (± 6.3%) |
250 ops/s (± 3.6%) |
0.85 |
data-client: delete-item |
384.62 ops/s (± 5.2%) |
333.33 ops/s (± 4.6%) |
0.87 |
data-client: move-item |
241 ops/s (± 7.3%) |
192.31 ops/s (± 8.7%) |
0.80 |
This comment was automatically generated by workflow using github-action-benchmark.
There was a problem hiding this comment.
Benchmark
Details
| Benchmark suite | Current: 479badb | Previous: 8b3bb89 | Ratio |
|---|---|---|---|
normalizeLong |
426 ops/sec (±4.12%) |
464 ops/sec (±3.11%) |
1.09 |
normalizeLong Values |
395 ops/sec (±0.38%) |
413 ops/sec (±0.27%) |
1.05 |
normalizeLong Scalar |
360 ops/sec (±3.32%) |
393 ops/sec (±2.46%) |
1.09 |
normalizeLong Scalar update |
902 ops/sec (±0.17%) |
842 ops/sec (±0.46%) |
0.93 |
denormalizeLong |
236 ops/sec (±5.62%) |
273 ops/sec (±6.00%) |
1.16 |
denormalizeLong Values |
223 ops/sec (±4.74%) |
245 ops/sec (±5.48%) |
1.10 |
denormalizeLong donotcache |
1014 ops/sec (±0.81%) |
1171 ops/sec (±0.73%) |
1.15 |
denormalizeLong Values donotcache |
741 ops/sec (±0.23%) |
789 ops/sec (±0.42%) |
1.06 |
denormalizeLong Scalar donotcache |
1036 ops/sec (±0.33%) |
1159 ops/sec (±0.23%) |
1.12 |
denormalizeShort donotcache 500x |
1402 ops/sec (±0.12%) |
1486 ops/sec (±0.27%) |
1.06 |
denormalizeShort 500x |
647 ops/sec (±6.71%) |
670 ops/sec (±6.59%) |
1.04 |
denormalizeShort 500x withCache |
6631 ops/sec (±0.13%) |
6479 ops/sec (±1.00%) |
0.98 |
queryShort 500x withCache |
3112 ops/sec (±0.13%) |
3566 ops/sec (±1.05%) |
1.15 |
buildQueryKey All |
57065 ops/sec (±1.05%) |
61510 ops/sec (±0.58%) |
1.08 |
query All withCache |
6354 ops/sec (±2.79%) |
6976 ops/sec (±4.81%) |
1.10 |
denormalizeLong with mixin Entity |
214 ops/sec (±7.04%) |
250 ops/sec (±7.59%) |
1.17 |
denormalizeLong withCache |
7501 ops/sec (±0.20%) |
7085 ops/sec (±0.57%) |
0.94 |
denormalizeLong withCache (Scalar churn) |
7408 ops/sec (±0.61%) |
7140 ops/sec (±0.23%) |
0.96 |
denormalizeLong Values withCache |
5170 ops/sec (±1.32%) |
5623 ops/sec (±1.54%) |
1.09 |
denormalizeLong Scalar withCache |
7976 ops/sec (±0.41%) |
7069 ops/sec (±0.31%) |
0.89 |
denormalizeLong Scalar update withCache |
4085 ops/sec (±0.18%) |
3063 ops/sec (±0.06%) |
0.75 |
denormalizeLong All withCache |
6521 ops/sec (±0.16%) |
6083 ops/sec (±0.19%) |
0.93 |
denormalizeLong Query-sorted withCache |
6582 ops/sec (±2.13%) |
7136 ops/sec (±5.02%) |
1.08 |
denormalizeLongAndShort withEntityCacheOnly |
1823 ops/sec (±0.25%) |
1694 ops/sec (±0.46%) |
0.93 |
denormalize bidirectional 50 |
4648 ops/sec (±11.02%) |
5227 ops/sec (±11.81%) |
1.12 |
denormalize bidirectional 50 donotcache |
42376 ops/sec (±1.62%) |
48901 ops/sec (±0.45%) |
1.15 |
getResponse |
4440 ops/sec (±3.64%) |
4760 ops/sec (±4.78%) |
1.07 |
getResponse (null) |
9315280 ops/sec (±0.83%) |
11986909 ops/sec (±0.76%) |
1.29 |
getResponse (clear cache) |
196 ops/sec (±9.80%) |
248 ops/sec (±8.12%) |
1.27 |
getSmallResponse |
3367 ops/sec (±1.47%) |
4011 ops/sec (±1.29%) |
1.19 |
getSmallInferredResponse |
2837 ops/sec (±0.14%) |
3196 ops/sec (±0.96%) |
1.13 |
getResponse Collection |
4491 ops/sec (±3.16%) |
5257 ops/sec (±1.21%) |
1.17 |
get Collection |
2804 ops/sec (±0.50%) |
2372 ops/sec (±0.29%) |
0.85 |
get Query-sorted |
4956 ops/sec (±1.73%) |
5299 ops/sec (±2.05%) |
1.07 |
setLong |
441 ops/sec (±0.29%) |
470 ops/sec (±0.18%) |
1.07 |
setLongWithMerge |
250 ops/sec (±0.20%) |
267 ops/sec (±0.81%) |
1.07 |
setLongWithSimpleMerge |
271 ops/sec (±0.20%) |
285 ops/sec (±0.20%) |
1.05 |
setSmallResponse 500x |
914 ops/sec (±1.19%) |
992 ops/sec (±1.35%) |
1.09 |
setMany 50x one-per-row |
145 ops/sec (±0.79%) |
196 ops/sec (±1.26%) |
1.35 |
setMany 50 batch |
3557 ops/sec (±2.76%) |
4162 ops/sec (±0.72%) |
1.17 |
setMany 500x one-per-row |
14.96 ops/sec (±0.82%) |
20.98 ops/sec (±2.00%) |
1.40 |
setMany 500 batch |
1390 ops/sec (±3.27%) |
1408 ops/sec (±0.20%) |
1.01 |
This comment was automatically generated by workflow using github-action-benchmark.
There was a problem hiding this comment.
Benchmark Spread
Details
| Benchmark suite | Current: 479badb | Previous: 38dbb52 | Ratio |
|---|---|---|---|
setOneEntity in 10k entity store |
156 ops/sec (±0.77%) |
153 ops/sec (±0.97%) |
0.98 |
This comment was automatically generated by workflow using github-action-benchmark.
…y types The esmodule relevance flag now uses a denylist of provably irrelevant paths, so new inputs run the esmodule jobs by default. rest's legacy types build uses scripts/build-legacy-types.sh (direct downlevel-dts, d.ts-only copies) with --newer-overlays-last to keep its overlay order; ts4.0/ts4.1 output is byte-identical (8.6s -> 4.5s locally). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EEcQdob4nGVuMq91oUHC2V
… paths Downlevel always runs first; --inherit-newer-overlays (rest) then applies earlier versions' custom types. Without the flag those copies were always overwritten by downlevel-dts, so endpoint/normalizr output is unchanged (ts*/ byte-identical). The esmodule and tests relevance checks now share one DOCS_ONLY path list. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EEcQdob4nGVuMq91oUHC2V
* fix(types): Apply newer legacy type overlays to older TS outputs endpoint and normalizr legacy outputs (ts4.2, ts4.0, ts3.4) now inherit every newer version's src-*-types overlay, as rest already did. This replaces the TS 5.4 NoInfer builtin with the NI<T> = T fallback for TS < 4.8 consumers. normalizr re-exports memo types by name instead of `export type *` (TS 5.0 syntax that downlevel-dts leaves as is). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MpCgcZt8G8R5KARZ7z5CKE * docs(blog): Note legacy TypeScript types fix Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MpCgcZt8G8R5KARZ7z5CKE --------- Co-authored-by: Claude <noreply@anthropic.com>
#4140) * fix(types): Apply newer legacy type overlays to older TS outputs endpoint and normalizr legacy outputs (ts4.2, ts4.0, ts3.4) now inherit every newer version's src-*-types overlay, as rest already did. This replaces the TS 5.4 NoInfer builtin with the NI<T> = T fallback for TS < 4.8 consumers. normalizr re-exports memo types by name instead of `export type *` (TS 5.0 syntax that downlevel-dts leaves as is). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MpCgcZt8G8R5KARZ7z5CKE * docs(blog): Note legacy TypeScript types fix Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MpCgcZt8G8R5KARZ7z5CKE * fix(types): Fix endpoint/rest legacy type errors with skipLibCheck off - TS 4.0: unroll RemoveArray and approximate PartialArray (recursive conditional types need 4.1) in new src-4.0-types overlays - TS <4.2: rewrite `abstract new` to `new` in the downleveled output and drop the stale src-4.0-types Entity/EntityTypes copies - TS 4.2: ConstructorInstance<> replaces InstanceType<> on abstract TBase - TS 4.2-4.4: UnionInstance Args is unconstrained - TS 4.0-4.5: rest getPage narrows paginationField with Extract<> - CI: esmodule-types also typechecks a skipLibCheck: false consumer Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMEHZGboXdMFRkF4D2ktki * docs(blog): Link #4140 in v0.19 notes Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMEHZGboXdMFRkF4D2ktki * refactor(types): Isolate recursive tuple types so the 4.0 overlay is one small file - RemoveArray and PartialArray move to tupleTypes.ts; the src-4.0-types overlay replaces only that module instead of copying endpointTypes/utility - Legacy build only rewrites files that contain `abstract new (` - libcheck typetest skips TypeScript's own lib checks - Split the legacy types bullet in ci-config.mdc Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMEHZGboXdMFRkF4D2ktki * internal: Resolve leftover merge conflict in ci-config rule Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMEHZGboXdMFRkF4D2ktki * internal: Resolve leftover merge conflict in build-legacy-types.sh Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AMEHZGboXdMFRkF4D2ktki --------- Co-authored-by: Claude <noreply@anthropic.com>
350c124 to
182344b
Compare
version_lt compares major.minor in bash instead of relying on sort -V (a missing -V silently skipped the abstract new rewrite), and the abstract new grep no longer fails the build under pipefail when nothing matches. esmodule-types-latest also runs the skipLibCheck: false typetest so lib/ is checked on the newest compiler. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EEcQdob4nGVuMq91oUHC2V
Requested by Nathaniel · project thread
Follow-ups from #4112, plus #4138 and #4140 (both merged into this branch).
Motivation
TypeScript 4.x users with
skipLibCheckoff got errors from@data-client/endpoint,@data-client/normalizrand@data-client/restdeclarations (from the changesets):CI: the esmodule relevance flag in
setupused an allowlist, so a new input path would silently skip the esmodule jobs. rest's legacy types build paid several yarn and copyfiles boots insidesetup.Solution
scripts/build-legacy-types.shdownlevels first, then applies every newer version'ssrc-*-types, then the version's own. endpoint/normalizr never actually inherited newer overlays before (the copies ran beforedownlevel-dtsoverwrote them), so e.g. endpointts4.2shipped the TS 5.4NoInferbuiltin. normalizr re-exports memo types by name instead ofexport type *.abstract new→newfor outputs below 4.2 (replacing drifted hand-copiedEntityoverlays),ConstructorInstance<>for TS 4.2, and agetPagenarrowing fix for rest.esmodule-typesnow also type-checksexamples/todo-app/tsconfig.typetest-libcheck.jsonwithskipLibCheck: false.downlevel-dts, d.ts-only copies, versions in parallel): 8.6s to 4.5s locally.DOCS_ONLYpaths (also thetestsdenylist) plus.vscode/,plans/, root__tests__/,eslint.config.mjs,jest.config.js,examples/*.md, and the examples the esmodule jobs never build. Unknown paths run the jobs (fail open)..cursor/rules/ci-config.mdcupdated.Open questions
Not done, with reasons:
.yarn/cachefrom it): typecheck finishes ~24–30s aftersetupincluding spin-up, attach andtsc, so attach costs well under that. 11 of 16 downstream jobs runyarn up/yarn addand would need the cache viarestore_cache, so the saving on the other 5 is a few seconds.unit_tests-latest: at most ~10s to gain (it finishes ~11s after the next-slowest job), while a second shard pays its own spin-up and attach and needs merged coverage for codecov.ts3.4/, untested in CI) still reports pre-existingSnapshotInterface.d.tsrest-element errors (noted in fix(types): Fix endpoint/rest legacy type errors with skipLibCheck off #4140).🤖 Generated with Claude Code
https://claude.ai/code/session_01EEcQdob4nGVuMq91oUHC2V
Note
Medium Risk
Changes published
.d.tsoverlays and legacy build ordering across endpoint, normalizr, and rest; CI relevance logic is inverted but intentionally fail-open.Overview
Fixes published declaration errors for consumers on TypeScript 4.0–4.7 with
skipLibCheck: false:NoInfer/export type *issues in normalizr, andEntity/Endpoint/Union/RestEndpointbreakage on 4.0–4.5 (circularRemoveArray, abstract constructors, pagination narrowing).Legacy types pipeline:
build-legacy-types.shnow downlevelslibfirst, then layerssrc-*-typesoverlays (fixing overlays being wiped before), rewritesabstract new→newfor outputs below 4.2, and@data-client/restuses the shared script. TS 4.0 gets a non-recursivetupleTypesoverlay; source addsConstructorInstance<>, sharedtupleTypes, and looserUnionargs; hand-maintained TS 4.0Entitycopies are removed.CI: Esmodule job skipping switches from an allowlist to a denylist (unknown paths still run). The esmodule-types matrix adds
typetest-libcheckwithskipLibCheck: false(plus bundler resolution on latest TS) so legacytypesVersionsoutputs are type-checked in CI. Docs/changesets/blog note the fixes.Reviewed by Cursor Bugbot for commit 479badb. Bugbot is set up for automated code reviews on this repo. Configure here.