From 35af027d518ab2b8b8c1132b69c1a5fa95a89a32 Mon Sep 17 00:00:00 2001 From: Salah-Eddine Saakoun Date: Wed, 9 Sep 2026 22:21:26 +0200 Subject: [PATCH 1/4] chore: type check tests via lint:tsc --- package.json | 3 ++- tsconfig.lint.json | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 tsconfig.lint.json diff --git a/package.json b/package.json index 4a8ac0332..4323831ec 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "build:clean": "yarn build:only-clean && yarn build", "build:docs": "typedoc", "build:only-clean": "rimraf ./dist ./tsconfig.build.tsbuildinfo", - "lint": "yarn lint:eslint && yarn lint:constraints && yarn lint:misc --check && yarn lint:dependencies && yarn lint:changelog", + "lint": "yarn lint:tsc && yarn lint:eslint && yarn lint:constraints && yarn lint:misc --check && yarn lint:dependencies && yarn lint:changelog", "lint:changelog": "auto-changelog validate --prettier", "lint:constraints": "yarn constraints", "lint:dependencies": "knip --config knip.config.mts --dependencies && yarn dedupe --check", @@ -45,6 +45,7 @@ "lint:eslint": "eslint . --cache", "lint:fix": "yarn lint:eslint --fix && yarn lint:constraints --fix && yarn lint:misc --write && yarn lint:dependencies:fix && yarn lint:changelog", "lint:misc": "oxfmt --ignore-path .gitignore", + "lint:tsc": "tsc --noEmit --project tsconfig.lint.json", "prepack": "./scripts/prepack.sh", "test": "yarn test:source && yarn test:types", "test:source": "jest && jest-it-up --config jest.config.cjs", diff --git a/tsconfig.lint.json b/tsconfig.lint.json new file mode 100644 index 000000000..eea194ff1 --- /dev/null +++ b/tsconfig.lint.json @@ -0,0 +1,23 @@ +{ + /** + * Type checks everything the build does not: tests, fixtures and the config + * files at the root. `tsconfig.build.json` only covers `src` minus tests, and + * ts-jest runs in transpile-only mode because `isolatedModules` is set, so + * without this nothing checks the types in a test file. + */ + "extends": "./tsconfig.json", + "compilerOptions": { + /** + * Dependencies ship declarations that do not satisfy the strict flags used + * here, and their errors are not ours to fix. + */ + "skipLibCheck": true + }, + /** + * `*.test-d.ts` files belong to `tsd`, which type checks them itself via + * `yarn test:types`. Pulling them in here would drag `tsd`'s own types into + * the program, and those reference `lib="esnext"`, which widens built in + * types like `ReadonlySet` well beyond the `lib` this package targets. + */ + "exclude": ["./dist/**/*", "./src/**/*.test-d.ts"] +} From 6cd2af00c23b425ebc352a6164bc59529cf2a926 Mon Sep 17 00:00:00 2001 From: Salah-Eddine Saakoun Date: Thu, 10 Sep 2026 16:00:28 +0200 Subject: [PATCH 2/4] chore: drop the redundant noEmit flag --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4323831ec..b61152fd4 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "lint:eslint": "eslint . --cache", "lint:fix": "yarn lint:eslint --fix && yarn lint:constraints --fix && yarn lint:misc --write && yarn lint:dependencies:fix && yarn lint:changelog", "lint:misc": "oxfmt --ignore-path .gitignore", - "lint:tsc": "tsc --noEmit --project tsconfig.lint.json", + "lint:tsc": "tsc --project tsconfig.lint.json", "prepack": "./scripts/prepack.sh", "test": "yarn test:source && yarn test:types", "test:source": "jest && jest-it-up --config jest.config.cjs", From 9d77f971063f6c9f7d9e59e77893b725d7f70876 Mon Sep 17 00:00:00 2001 From: Salah-Eddine Saakoun Date: Thu, 10 Sep 2026 16:42:47 +0200 Subject: [PATCH 3/4] chore: emit lint typecheck output to a cached directory --- .gitignore | 1 + tsconfig.lint.json | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d54c2ba01..fa309c9ef 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ node_modules/ # TypeScript cache *.tsbuildinfo +**/.tsc-lint-cache/ # Optional npm cache directory .npm diff --git a/tsconfig.lint.json b/tsconfig.lint.json index eea194ff1..a4cf1e123 100644 --- a/tsconfig.lint.json +++ b/tsconfig.lint.json @@ -11,7 +11,21 @@ * Dependencies ship declarations that do not satisfy the strict flags used * here, and their errors are not ours to fix. */ - "skipLibCheck": true + "skipLibCheck": true, + /** + * Emit into a hidden, git ignored cache directory, matching how `lint:tsc` + * works in core. Emitting is what makes `tsBuildInfoFile` meaningful, so + * repeat runs only check what changed. Only declarations are written, since + * the JavaScript would be thrown away. `tsconfig.json` sets `noEmit` for the + * editor and `tsconfig.build.json` owns the real build, so both are + * overridden here rather than the other way round. + */ + "noEmit": false, + "declaration": true, + "emitDeclarationOnly": true, + "incremental": true, + "outDir": "./.tsc-lint-cache", + "tsBuildInfoFile": "./.tsc-lint-cache/tsconfig.tsbuildinfo" }, /** * `*.test-d.ts` files belong to `tsd`, which type checks them itself via From 670fa8aa1187a15a6935a75ea693271e6e4e1fb5 Mon Sep 17 00:00:00 2001 From: Salah-Eddine Saakoun Date: Thu, 10 Sep 2026 16:45:08 +0200 Subject: [PATCH 4/4] chore: ignore the lint typecheck cache in eslint --- eslint.config.mjs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 1739e1dce..ca3a45bd7 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -11,7 +11,13 @@ const tsconfigRootDir = path.dirname(fileURLToPath(import.meta.url)); const config = createConfig([ ...base, { - ignores: ['coverage/**', 'dist/**', 'docs/**', '.yarn/**'], + ignores: [ + '**/.tsc-lint-cache', + 'coverage/**', + 'dist/**', + 'docs/**', + '.yarn/**', + ], }, { linterOptions: {