From 2983d9f71532c694bb262957f0972c3418e71b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20C=C3=B4t=C3=A9?= Date: Mon, 30 Mar 2026 10:59:35 -0400 Subject: [PATCH 1/8] fix(build): exclude config files from production DTS rollup The `experimentalDts` option in tsup respects the tsconfig `include` array to determine which files are in scope for DTS generation. Each package's `tsconfig.json` includes `*.config.*` for IDE support, and `tsconfig.prod.json` inherited this without overriding it. This caused `vite.config.ts` and `tsup.config.ts` to be swept into the DTS rollup, leaking `import { UserConfig } from 'vite'` into published types. Since vite references `@types/node`, this globally overrides the DOM `setTimeout` return type from `number` to `NodeJS.Timeout` for all consumers. Add `"include": ["src"]` (and `"exclude": ["src/__tests__"]` where applicable) to all `tsconfig.prod.json` files that were missing it, matching the pattern already used by query-core, react-query, preact-query, and solid-query. --- packages/angular-query-experimental/tsconfig.prod.json | 4 +++- packages/angular-query-persist-client/tsconfig.prod.json | 4 +++- packages/eslint-plugin-query/tsconfig.prod.json | 4 +++- packages/preact-query-devtools/tsconfig.prod.json | 4 +++- packages/preact-query-persist-client/tsconfig.prod.json | 4 +++- packages/query-async-storage-persister/tsconfig.prod.json | 4 +++- .../query-broadcast-client-experimental/tsconfig.prod.json | 4 +++- packages/query-devtools/tsconfig.prod.json | 4 +++- packages/query-persist-client-core/tsconfig.prod.json | 4 +++- packages/query-sync-storage-persister/tsconfig.prod.json | 4 +++- packages/react-query-devtools/tsconfig.prod.json | 4 +++- packages/react-query-next-experimental/tsconfig.prod.json | 3 ++- packages/react-query-persist-client/tsconfig.prod.json | 4 +++- packages/solid-query-devtools/tsconfig.prod.json | 4 +++- packages/solid-query-persist-client/tsconfig.prod.json | 4 +++- packages/vue-query/tsconfig.prod.json | 4 +++- 16 files changed, 47 insertions(+), 16 deletions(-) diff --git a/packages/angular-query-experimental/tsconfig.prod.json b/packages/angular-query-experimental/tsconfig.prod.json index b470042ddc1..955d36c73e0 100644 --- a/packages/angular-query-experimental/tsconfig.prod.json +++ b/packages/angular-query-experimental/tsconfig.prod.json @@ -5,5 +5,7 @@ "composite": false, "rootDir": "../../", "customConditions": null - } + }, + "include": ["src"], + "exclude": ["src/__tests__"] } diff --git a/packages/angular-query-persist-client/tsconfig.prod.json b/packages/angular-query-persist-client/tsconfig.prod.json index 0f4c92da065..2bb29fdf02a 100644 --- a/packages/angular-query-persist-client/tsconfig.prod.json +++ b/packages/angular-query-persist-client/tsconfig.prod.json @@ -4,5 +4,7 @@ "incremental": false, "composite": false, "rootDir": "../../" - } + }, + "include": ["src"], + "exclude": ["src/__tests__"] } diff --git a/packages/eslint-plugin-query/tsconfig.prod.json b/packages/eslint-plugin-query/tsconfig.prod.json index 0f4c92da065..2bb29fdf02a 100644 --- a/packages/eslint-plugin-query/tsconfig.prod.json +++ b/packages/eslint-plugin-query/tsconfig.prod.json @@ -4,5 +4,7 @@ "incremental": false, "composite": false, "rootDir": "../../" - } + }, + "include": ["src"], + "exclude": ["src/__tests__"] } diff --git a/packages/preact-query-devtools/tsconfig.prod.json b/packages/preact-query-devtools/tsconfig.prod.json index f39338ce4ce..2de70e52771 100644 --- a/packages/preact-query-devtools/tsconfig.prod.json +++ b/packages/preact-query-devtools/tsconfig.prod.json @@ -5,5 +5,7 @@ "composite": false, "rootDir": "../../", "customConditions": [] - } + }, + "include": ["src"], + "exclude": ["src/__tests__"] } diff --git a/packages/preact-query-persist-client/tsconfig.prod.json b/packages/preact-query-persist-client/tsconfig.prod.json index 0f4c92da065..2bb29fdf02a 100644 --- a/packages/preact-query-persist-client/tsconfig.prod.json +++ b/packages/preact-query-persist-client/tsconfig.prod.json @@ -4,5 +4,7 @@ "incremental": false, "composite": false, "rootDir": "../../" - } + }, + "include": ["src"], + "exclude": ["src/__tests__"] } diff --git a/packages/query-async-storage-persister/tsconfig.prod.json b/packages/query-async-storage-persister/tsconfig.prod.json index 0f4c92da065..2bb29fdf02a 100644 --- a/packages/query-async-storage-persister/tsconfig.prod.json +++ b/packages/query-async-storage-persister/tsconfig.prod.json @@ -4,5 +4,7 @@ "incremental": false, "composite": false, "rootDir": "../../" - } + }, + "include": ["src"], + "exclude": ["src/__tests__"] } diff --git a/packages/query-broadcast-client-experimental/tsconfig.prod.json b/packages/query-broadcast-client-experimental/tsconfig.prod.json index 0f4c92da065..2bb29fdf02a 100644 --- a/packages/query-broadcast-client-experimental/tsconfig.prod.json +++ b/packages/query-broadcast-client-experimental/tsconfig.prod.json @@ -4,5 +4,7 @@ "incremental": false, "composite": false, "rootDir": "../../" - } + }, + "include": ["src"], + "exclude": ["src/__tests__"] } diff --git a/packages/query-devtools/tsconfig.prod.json b/packages/query-devtools/tsconfig.prod.json index 0f4c92da065..2bb29fdf02a 100644 --- a/packages/query-devtools/tsconfig.prod.json +++ b/packages/query-devtools/tsconfig.prod.json @@ -4,5 +4,7 @@ "incremental": false, "composite": false, "rootDir": "../../" - } + }, + "include": ["src"], + "exclude": ["src/__tests__"] } diff --git a/packages/query-persist-client-core/tsconfig.prod.json b/packages/query-persist-client-core/tsconfig.prod.json index 0f4c92da065..2bb29fdf02a 100644 --- a/packages/query-persist-client-core/tsconfig.prod.json +++ b/packages/query-persist-client-core/tsconfig.prod.json @@ -4,5 +4,7 @@ "incremental": false, "composite": false, "rootDir": "../../" - } + }, + "include": ["src"], + "exclude": ["src/__tests__"] } diff --git a/packages/query-sync-storage-persister/tsconfig.prod.json b/packages/query-sync-storage-persister/tsconfig.prod.json index 0f4c92da065..2bb29fdf02a 100644 --- a/packages/query-sync-storage-persister/tsconfig.prod.json +++ b/packages/query-sync-storage-persister/tsconfig.prod.json @@ -4,5 +4,7 @@ "incremental": false, "composite": false, "rootDir": "../../" - } + }, + "include": ["src"], + "exclude": ["src/__tests__"] } diff --git a/packages/react-query-devtools/tsconfig.prod.json b/packages/react-query-devtools/tsconfig.prod.json index f39338ce4ce..2de70e52771 100644 --- a/packages/react-query-devtools/tsconfig.prod.json +++ b/packages/react-query-devtools/tsconfig.prod.json @@ -5,5 +5,7 @@ "composite": false, "rootDir": "../../", "customConditions": [] - } + }, + "include": ["src"], + "exclude": ["src/__tests__"] } diff --git a/packages/react-query-next-experimental/tsconfig.prod.json b/packages/react-query-next-experimental/tsconfig.prod.json index 0f4c92da065..9abd7f0ffac 100644 --- a/packages/react-query-next-experimental/tsconfig.prod.json +++ b/packages/react-query-next-experimental/tsconfig.prod.json @@ -4,5 +4,6 @@ "incremental": false, "composite": false, "rootDir": "../../" - } + }, + "include": ["src"] } diff --git a/packages/react-query-persist-client/tsconfig.prod.json b/packages/react-query-persist-client/tsconfig.prod.json index 0f4c92da065..2bb29fdf02a 100644 --- a/packages/react-query-persist-client/tsconfig.prod.json +++ b/packages/react-query-persist-client/tsconfig.prod.json @@ -4,5 +4,7 @@ "incremental": false, "composite": false, "rootDir": "../../" - } + }, + "include": ["src"], + "exclude": ["src/__tests__"] } diff --git a/packages/solid-query-devtools/tsconfig.prod.json b/packages/solid-query-devtools/tsconfig.prod.json index 0f4c92da065..2bb29fdf02a 100644 --- a/packages/solid-query-devtools/tsconfig.prod.json +++ b/packages/solid-query-devtools/tsconfig.prod.json @@ -4,5 +4,7 @@ "incremental": false, "composite": false, "rootDir": "../../" - } + }, + "include": ["src"], + "exclude": ["src/__tests__"] } diff --git a/packages/solid-query-persist-client/tsconfig.prod.json b/packages/solid-query-persist-client/tsconfig.prod.json index 0f4c92da065..2bb29fdf02a 100644 --- a/packages/solid-query-persist-client/tsconfig.prod.json +++ b/packages/solid-query-persist-client/tsconfig.prod.json @@ -4,5 +4,7 @@ "incremental": false, "composite": false, "rootDir": "../../" - } + }, + "include": ["src"], + "exclude": ["src/__tests__"] } diff --git a/packages/vue-query/tsconfig.prod.json b/packages/vue-query/tsconfig.prod.json index 0f4c92da065..2bb29fdf02a 100644 --- a/packages/vue-query/tsconfig.prod.json +++ b/packages/vue-query/tsconfig.prod.json @@ -4,5 +4,7 @@ "incremental": false, "composite": false, "rootDir": "../../" - } + }, + "include": ["src"], + "exclude": ["src/__tests__"] } From 58feb9ed4077e9486cf981008ac2d11b4e440e58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20C=C3=B4t=C3=A9?= Date: Mon, 30 Mar 2026 14:21:14 -0400 Subject: [PATCH 2/8] chore: add changeset for DTS type pollution fix --- .changeset/fix-dts-type-pollution.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fix-dts-type-pollution.md diff --git a/.changeset/fix-dts-type-pollution.md b/.changeset/fix-dts-type-pollution.md new file mode 100644 index 00000000000..32ce9083b8c --- /dev/null +++ b/.changeset/fix-dts-type-pollution.md @@ -0,0 +1,5 @@ +--- +'@tanstack/react-query-devtools': patch +--- + +fix(build): exclude config files from production DTS rollup to prevent `@types/node` type pollution From caad915a52a449a520a43cc9db14ac34860a8469 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20C=C3=B4t=C3=A9?= Date: Mon, 30 Mar 2026 15:08:23 -0400 Subject: [PATCH 3/8] test(build): add regression test for build tool type leaks in .d.ts files Adds scripts/verify-dts-imports.ts that scans all published .d.ts files for forbidden imports from build tools (vite, tsup, vitest) and `/// `. Wired into test:pr and test:ci to run after the build completes. --- package.json | 5 ++-- scripts/verify-dts-imports.ts | 47 +++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 scripts/verify-dts-imports.ts diff --git a/package.json b/package.json index e4e28cb5d55..937c0f0e73a 100644 --- a/package.json +++ b/package.json @@ -10,14 +10,15 @@ "scripts": { "clean": "pnpm --filter \"./packages/**\" run clean", "test": "pnpm run test:ci", - "test:pr": "nx affected --targets=test:sherif,test:knip,test:docs,test:eslint,test:lib,test:types,test:build,build", - "test:ci": "nx run-many --targets=test:sherif,test:knip,test:docs,test:eslint,test:lib,test:types,test:build,build", + "test:pr": "nx affected --targets=test:sherif,test:knip,test:docs,test:eslint,test:lib,test:types,test:build,build && pnpm run test:build:dts", + "test:ci": "nx run-many --targets=test:sherif,test:knip,test:docs,test:eslint,test:lib,test:types,test:build,build && pnpm run test:build:dts", "test:eslint": "nx affected --target=test:eslint", "test:sherif": "sherif -i typescript -p \"./integrations/*\" -p \"./examples/*\"", "test:size": "size-limit", "test:lib": "nx affected --target=test:lib --exclude=examples/**", "test:lib:dev": "pnpm run test:lib && nx watch --all -- pnpm run test:lib", "test:build": "nx affected --target=test:build --exclude=examples/**", + "test:build:dts": "node scripts/verify-dts-imports.ts", "test:types": "nx affected --target=test:types --exclude=examples/**", "test:knip": "knip --treat-config-hints-as-errors", "test:docs": "node scripts/verify-links.ts", diff --git a/scripts/verify-dts-imports.ts b/scripts/verify-dts-imports.ts new file mode 100644 index 00000000000..c4fd731fd0f --- /dev/null +++ b/scripts/verify-dts-imports.ts @@ -0,0 +1,47 @@ +import { readFileSync } from 'node:fs' +import { glob } from 'tinyglobby' + +const FORBIDDEN_PATTERNS = [ + /\bfrom\s+['"]vite['"]/, + /\bfrom\s+['"]tsup['"]/, + /\bfrom\s+['"]vitest/, + /\/\/\/\s*/, +] + +const errors: Array<{ file: string; line: number; text: string }> = [] + +const files = await glob(['packages/*/build/**/*.d.ts', 'packages/*/build/**/*.d.cts']) + +for (const file of files) { + const content = readFileSync(file, 'utf-8') + const lines = content.split('\n') + for (let i = 0; i < lines.length; i++) { + const line = lines[i]! + for (const pattern of FORBIDDEN_PATTERNS) { + if (pattern.test(line)) { + errors.push({ file, line: i + 1, text: line.trim() }) + } + } + } +} + +if (errors.length > 0) { + console.error( + 'ERROR: Build tool types leaked into published .d.ts files:\n', + ) + for (const error of errors) { + console.error(` ${error.file}:${error.line}`) + console.error(` ${error.text}\n`) + } + console.error( + 'This usually means a tsconfig.prod.json is missing "include": ["src"].', + ) + console.error( + 'See https://github.com/TanStack/query/issues/10294 for details.', + ) + process.exit(1) +} else { + console.log( + `Verified ${files.length} .d.ts files — no build tool type leaks found.`, + ) +} From 84b16af90c32a295820bcdab7a4f6399cad5b34d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20C=C3=B4t=C3=A9?= Date: Mon, 30 Mar 2026 16:09:53 -0400 Subject: [PATCH 4/8] fix(build): fail fast when no .d.ts files found in verify-dts-imports --- scripts/verify-dts-imports.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/verify-dts-imports.ts b/scripts/verify-dts-imports.ts index c4fd731fd0f..ee413b72525 100644 --- a/scripts/verify-dts-imports.ts +++ b/scripts/verify-dts-imports.ts @@ -12,6 +12,13 @@ const errors: Array<{ file: string; line: number; text: string }> = [] const files = await glob(['packages/*/build/**/*.d.ts', 'packages/*/build/**/*.d.cts']) +if (files.length === 0) { + console.error( + 'ERROR: No declaration files found under packages/*/build. Ensure the build step produced .d.ts outputs before verification.', + ) + process.exit(1) +} + for (const file of files) { const content = readFileSync(file, 'utf-8') const lines = content.split('\n') From d564c9fbdd3de223c9a0ae2171c6989f1ababa60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20C=C3=B4t=C3=A9?= Date: Mon, 30 Mar 2026 16:12:33 -0400 Subject: [PATCH 5/8] chore: add exclude for consistency in react-query-next-experimental --- packages/react-query-next-experimental/tsconfig.prod.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/react-query-next-experimental/tsconfig.prod.json b/packages/react-query-next-experimental/tsconfig.prod.json index 9abd7f0ffac..2bb29fdf02a 100644 --- a/packages/react-query-next-experimental/tsconfig.prod.json +++ b/packages/react-query-next-experimental/tsconfig.prod.json @@ -5,5 +5,6 @@ "composite": false, "rootDir": "../../" }, - "include": ["src"] + "include": ["src"], + "exclude": ["src/__tests__"] } From 3f0e4a57ef27b9f0b911f3bb257fa60bde9597d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20C=C3=B4t=C3=A9?= Date: Mon, 30 Mar 2026 16:20:51 -0400 Subject: [PATCH 6/8] chore: fix log message to mention both .d.ts and .d.cts files --- scripts/verify-dts-imports.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/verify-dts-imports.ts b/scripts/verify-dts-imports.ts index ee413b72525..4722bfc15c1 100644 --- a/scripts/verify-dts-imports.ts +++ b/scripts/verify-dts-imports.ts @@ -49,6 +49,6 @@ if (errors.length > 0) { process.exit(1) } else { console.log( - `Verified ${files.length} .d.ts files — no build tool type leaks found.`, + `Verified ${files.length} declaration files (.d.ts/.d.cts) — no build tool type leaks found.`, ) } From 1996cc94abf1dd7d10fb16219c65de35a10fcd11 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 14:14:28 +0000 Subject: [PATCH 7/8] ci: apply automated fixes --- scripts/verify-dts-imports.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/scripts/verify-dts-imports.ts b/scripts/verify-dts-imports.ts index 4722bfc15c1..8e9d87d4328 100644 --- a/scripts/verify-dts-imports.ts +++ b/scripts/verify-dts-imports.ts @@ -10,7 +10,10 @@ const FORBIDDEN_PATTERNS = [ const errors: Array<{ file: string; line: number; text: string }> = [] -const files = await glob(['packages/*/build/**/*.d.ts', 'packages/*/build/**/*.d.cts']) +const files = await glob([ + 'packages/*/build/**/*.d.ts', + 'packages/*/build/**/*.d.cts', +]) if (files.length === 0) { console.error( @@ -33,9 +36,7 @@ for (const file of files) { } if (errors.length > 0) { - console.error( - 'ERROR: Build tool types leaked into published .d.ts files:\n', - ) + console.error('ERROR: Build tool types leaked into published .d.ts files:\n') for (const error of errors) { console.error(` ${error.file}:${error.line}`) console.error(` ${error.text}\n`) From 668d758cb3bd443284f42ecb61d7232e480592c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20C=C3=B4t=C3=A9?= Date: Tue, 31 Mar 2026 10:29:08 -0400 Subject: [PATCH 8/8] chore: remove verify-dts-imports script and related package.json changes --- package.json | 5 ++-- scripts/verify-dts-imports.ts | 55 ----------------------------------- 2 files changed, 2 insertions(+), 58 deletions(-) delete mode 100644 scripts/verify-dts-imports.ts diff --git a/package.json b/package.json index 937c0f0e73a..e4e28cb5d55 100644 --- a/package.json +++ b/package.json @@ -10,15 +10,14 @@ "scripts": { "clean": "pnpm --filter \"./packages/**\" run clean", "test": "pnpm run test:ci", - "test:pr": "nx affected --targets=test:sherif,test:knip,test:docs,test:eslint,test:lib,test:types,test:build,build && pnpm run test:build:dts", - "test:ci": "nx run-many --targets=test:sherif,test:knip,test:docs,test:eslint,test:lib,test:types,test:build,build && pnpm run test:build:dts", + "test:pr": "nx affected --targets=test:sherif,test:knip,test:docs,test:eslint,test:lib,test:types,test:build,build", + "test:ci": "nx run-many --targets=test:sherif,test:knip,test:docs,test:eslint,test:lib,test:types,test:build,build", "test:eslint": "nx affected --target=test:eslint", "test:sherif": "sherif -i typescript -p \"./integrations/*\" -p \"./examples/*\"", "test:size": "size-limit", "test:lib": "nx affected --target=test:lib --exclude=examples/**", "test:lib:dev": "pnpm run test:lib && nx watch --all -- pnpm run test:lib", "test:build": "nx affected --target=test:build --exclude=examples/**", - "test:build:dts": "node scripts/verify-dts-imports.ts", "test:types": "nx affected --target=test:types --exclude=examples/**", "test:knip": "knip --treat-config-hints-as-errors", "test:docs": "node scripts/verify-links.ts", diff --git a/scripts/verify-dts-imports.ts b/scripts/verify-dts-imports.ts deleted file mode 100644 index 8e9d87d4328..00000000000 --- a/scripts/verify-dts-imports.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { readFileSync } from 'node:fs' -import { glob } from 'tinyglobby' - -const FORBIDDEN_PATTERNS = [ - /\bfrom\s+['"]vite['"]/, - /\bfrom\s+['"]tsup['"]/, - /\bfrom\s+['"]vitest/, - /\/\/\/\s*/, -] - -const errors: Array<{ file: string; line: number; text: string }> = [] - -const files = await glob([ - 'packages/*/build/**/*.d.ts', - 'packages/*/build/**/*.d.cts', -]) - -if (files.length === 0) { - console.error( - 'ERROR: No declaration files found under packages/*/build. Ensure the build step produced .d.ts outputs before verification.', - ) - process.exit(1) -} - -for (const file of files) { - const content = readFileSync(file, 'utf-8') - const lines = content.split('\n') - for (let i = 0; i < lines.length; i++) { - const line = lines[i]! - for (const pattern of FORBIDDEN_PATTERNS) { - if (pattern.test(line)) { - errors.push({ file, line: i + 1, text: line.trim() }) - } - } - } -} - -if (errors.length > 0) { - console.error('ERROR: Build tool types leaked into published .d.ts files:\n') - for (const error of errors) { - console.error(` ${error.file}:${error.line}`) - console.error(` ${error.text}\n`) - } - console.error( - 'This usually means a tsconfig.prod.json is missing "include": ["src"].', - ) - console.error( - 'See https://github.com/TanStack/query/issues/10294 for details.', - ) - process.exit(1) -} else { - console.log( - `Verified ${files.length} declaration files (.d.ts/.d.cts) — no build tool type leaks found.`, - ) -}