ci: silence baseUrl deprecation in docs tsconfig under TS 6+#5921
ci: silence baseUrl deprecation in docs tsconfig under TS 6+#5921dokson wants to merge 1 commit into
baseUrl deprecation in docs tsconfig under TS 6+#5921Conversation
Commit e58ea4d added `packages/docs/tsconfig.test.json`, which extends `packages/docs/tsconfig.json` (`baseUrl: "."`). Under TS 6 the legacy `baseUrl` triggers a deprecation that vitest 4.x's typecheck integration re-emits as an Unhandled Source Error, failing `pnpm test` with `Errors 1 error` even when every test passes: TypeCheckError: Option 'baseUrl' is deprecated and will stop functioning in TypeScript 7.0. Specify compilerOption '"ignoreDeprecations" "6.0"' to silence this error. ❯ packages/docs/tsconfig.test.json:3:3 A source-level fix doesn't compose: TS 5.5 rejects `"6.0"` as `TS5103: Invalid value for '--ignoreDeprecations'`, and TS 6 isn't silenced by `"5.0"` for the `baseUrl` deprecation specifically. Removing `baseUrl` outright breaks Next.js asset imports (`Cannot find module '@/public/logo/...'`). Inject the option only on the non-5.5 matrix entries via `jq`, mirroring the pattern used elsewhere in the repo for similar TS-version deltas. Three consecutive local `pnpm test` runs on TS 6.0.3 confirm the unhandled error is gone deterministically; TS 5.5 is unchanged.
|
Reviewed PR #5921 — the fix is correct and well-scoped. Approved with an informational inline note. The conditional Task list (3/3 completed)
|
|
TL;DR — Adds a matrix-conditional CI step that injects Key changes
Summary | 1 file | 1 commit | base:
The fix is version-conditional because TS 5.5 rejects
|
There was a problem hiding this comment.
The fix is correct — e58ea4d broke CI by adding a docs tsconfig.test.json that inherits the long-standing baseUrl: ".", which TS 6 now deprecates. The conditional jq injection is the right approach given that ignoreDeprecations: "6.0" is invalid under TS 5.5 and removing baseUrl would require touching runtime Next.js imports. No issues found with the implementation.
Task list (3/3 completed)
- Checkout PR and read the diff
- Investigate the change and assess correctness
- Submit review
Claude Opus | 𝕏
| # baseUrl in packages/docs/tsconfig.json is deprecated under TS 6 | ||
| # and vitest's typecheck integration surfaces it as an unhandled | ||
| # error; TS 5.5 rejects "6.0", so inject only on newer matrix entries. | ||
| - if: matrix.typescript != '5.5' |
There was a problem hiding this comment.
Nit: if the matrix ever gains entries like "5.6" or "6.1", this condition still works correctly since only 5.5 is excluded. Worth noting the condition is version-string equality — not a semver comparison — so it's tied to the literal matrix values. Fine as-is.
There was a problem hiding this comment.
Reviewed — no issues found.
Task list (3/3 completed)
- Checkout PR and read the diff
- Investigate the change and assess correctness
- Submit review
Claude Opus | 𝕏
…nhacks#2854, colinhacks#2106) `.deepPartial()` was deprecated in v3.21.0 and removed in v4 because the underlying recursive `instanceof` traversal had structural problems (see colinhacks#2106): it could not see user-defined schema subclasses, accumulated edge cases for every new schema type, and silently broke on advanced shapes. The community has been asking for a working alternative ever since (colinhacks#2854, 60+ commenters). Adds a v4-native implementation that addresses the design concerns of colinhacks#2106 head-on: - Dispatches on `schema._zod.def.type`, not `instanceof`. Custom schemas with unknown `def.type` fall through to identity instead of being silently mishandled. Users intercept inside `fn` for custom rewriting. - Cycle-safe via a `Map<schema, RESOLVING|result>` cache. Lazy schemas unfold lazily so recursive shapes terminate; shared sub-schemas are visited once. Direct (non-`lazy`) cycles throw rather than loop. - Bottom-up rewrite as a primitive. `core.mapOnSchema(schema, fn)` is the general traversal; `deepPartial` is one line on top of it. `deepStrict`, `deepReadonly`, etc. become trivial follow-ups. - Covers the v4 def vocabulary: object, array, tuple (+rest), record, map, set, union (incl. discriminated union — discriminator metadata preserved by spreading `def`), intersection, optional, nullable, default, prefault, nonoptional, catch, readonly, promise, success, pipe, function, lazy. Leaves (primitives, enum, literal, transform, custom, file, etc.) returned untouched. `mapOnSchema` lives in `core/` so both `classic` and `mini` reuse it; each variant has its own thin `deepPartial` wired to its own `partial`. Traversal pattern adapted from Jaen's v3 `mapOnSchema` (Apache-2.0, https://gist.github.com/jaens/7e15ae1984bb338c86eb5e452dee3010). Implementation rewritten for v4: `def.type` dispatch instead of `instanceof`, schema construction via `core.clone` instead of `new ZodFoo(...)`, full v4 def coverage. ```ts const Node: z.ZodType = z.object({ name: z.string(), children: z.array(z.lazy(() => Node)).optional(), }); z.deepPartial(Node).parse({}); // ok z.deepPartial(Node).parse({ children: [{}] }); // ok ``` Adds 22 tests covering shallow + nested objects, arrays, tuples with rest, unions, optional/nullable wrappers, recursive (lazy) schemas, primitive leaf preservation, and `mapOnSchema` identity / targeted rewrites. CI on TS 6+ may surface the unrelated `baseUrl` deprecation error from colinhacks#5921 until that lands; this PR doesn't touch that path.
|
Superseded by 88015df ( Thanks 👍 |
…nhacks#2854, colinhacks#2106) `.deepPartial()` was deprecated in v3.21.0 and removed in v4 because the underlying recursive `instanceof` traversal had structural problems (see colinhacks#2106): it could not see user-defined schema subclasses, accumulated edge cases for every new schema type, and silently broke on advanced shapes. The community has been asking for a working alternative ever since (colinhacks#2854, 60+ commenters). Adds a v4-native implementation that addresses the design concerns of colinhacks#2106 head-on: - Dispatches on `schema._zod.def.type`, not `instanceof`. Custom schemas with unknown `def.type` fall through to identity instead of being silently mishandled. Users intercept inside `fn` for custom rewriting. - Cycle-safe via a `Map<schema, RESOLVING|result>` cache. Lazy schemas unfold lazily so recursive shapes terminate; shared sub-schemas are visited once. Direct (non-`lazy`) cycles throw rather than loop. - Bottom-up rewrite as a primitive. `core.mapOnSchema(schema, fn)` is the general traversal; `deepPartial` is one line on top of it. `deepStrict`, `deepReadonly`, etc. become trivial follow-ups. - Covers the v4 def vocabulary: object, array, tuple (+rest), record, map, set, union (incl. discriminated union — discriminator metadata preserved by spreading `def`), intersection, optional, nullable, default, prefault, nonoptional, catch, readonly, promise, success, pipe, function, lazy. Leaves (primitives, enum, literal, transform, custom, file, etc.) returned untouched. `mapOnSchema` lives in `core/` so both `classic` and `mini` reuse it; each variant has its own thin `deepPartial` wired to its own `partial`. Traversal pattern adapted from Jaen's v3 `mapOnSchema` (Apache-2.0, https://gist.github.com/jaens/7e15ae1984bb338c86eb5e452dee3010). Implementation rewritten for v4: `def.type` dispatch instead of `instanceof`, schema construction via `core.clone` instead of `new ZodFoo(...)`, full v4 def coverage. ```ts const Node: z.ZodType = z.object({ name: z.string(), children: z.array(z.lazy(() => Node)).optional(), }); z.deepPartial(Node).parse({}); // ok z.deepPartial(Node).parse({ children: [{}] }); // ok ``` Adds 22 tests covering shallow + nested objects, arrays, tuples with rest, unions, optional/nullable wrappers, recursive (lazy) schemas, primitive leaf preservation, and `mapOnSchema` identity / targeted rewrites. CI on TS 6+ may surface the unrelated `baseUrl` deprecation error from colinhacks#5921 until that lands; this PR doesn't touch that path.
Summary
Fixes the
pnpm testjob underTest with TypeScript latest(currently TS 6.0.3), which has been failing on every PR opened since e58ea4d (yesterday) with:All tests pass; the failure is a vitest-side classification of a TS deprecation as an unhandled error.
Root cause
Commit e58ea4d ("docs: test Zod Mini tab code heights", 2026-04-30) added a brand-new
packages/docs/tsconfig.test.json. That fileextendspackages/docs/tsconfig.json, which has carried"baseUrl": "."since long before TS deprecated it. Before e58ea4d, the docs package had no vitest typecheck setup, so the deprecation never reachedpnpm test. After e58ea4d it does, and vitest 4.x'stypecheck.checker: "tsc"re-emits TS source errors as test-runner unhandled errors → exit 1.This explains the recent CI breakage: PR #5914 (opened 2026-04-30 18:50 UTC, before the e58ea4d landed at 19:12 UTC) passes; PRs opened or rerun after that point fail. Same TypeScript 6.0.3, same vitest 4.1.5 — only the new docs tsconfig differs.
Why a source-level fix doesn't work
Tried first; closed PR #5920. Three things ruled out:
"ignoreDeprecations": "6.0"in source — TS 5.5 rejects withTS5103: Invalid value for '--ignoreDeprecations'and breaks theTest with TypeScript 5.5job."ignoreDeprecations": "5.0"in source — accepted by TS 5.5, but TS 6 still emits thebaseUrldeprecation under it (the deprecation message specifically demands"6.0").baseUrloutright — breaks Next.js asset imports inapp/layout.config.tsx:Cannot find module '@/public/logo/logo.png'. Removing it would require touching unrelated runtime code.So the fix has to be TS-version-conditional, which means workflow logic.
Fix
Add a single matrix-conditional
jqstep beforepnpm build, injectingignoreDeprecations: "6.0"intopackages/docs/tsconfig.jsononly when the matrix typescript value is not5.5. This mirrors the pattern already used in the repo (e.g. on thefix-tests-cibranch's commit 4e29983) for the same kind of TS-version delta on.configs/tsconfig.base.json.The patched file is only used for the duration of the CI run; nothing in source changes.
Verification
Reproduced and validated locally with TS 6.0.3 + vitest 4.1.5. Before the patch, the unhandled error appears on most runs; after applying the same
jqtransform manually, three consecutivepnpm testinvocations all complete withoutErrors 1 error. TS 5.5 path is unchanged (the conditional skips the patch).Scope
.github/workflows/test.yml(+8 lines).jqbinary is already available onubuntu-latestrunners.Alternative considered
The
fix-tests-cibranch's commit 4e29983 already adds a similarjqstep plus atypescript: "6"matrix entry andfail-fast: false, but it patches.configs/tsconfig.base.json(not the docs one) and isn't merged yet. If that branch lands first, the samejqinvocation can be folded into its block; the deltas don't conflict. Happy to defer or rebase if preferred.