From afe650debc970b68637b00fe383692b0ab7a5dda Mon Sep 17 00:00:00 2001 From: SandroMaglione Date: Sun, 1 Nov 2026 16:05:34 +0900 Subject: [PATCH] Check TypeScript 7 compatibility in pnpm check Pin the native TypeScript 7 compiler in a private tooling workspace package so its tsc binary does not replace the TypeScript 6 toolchain, type-check every package project and the test project with it, and compile the packed consumer fixture with both compilers. Fix the Machine test snapshot helpers so TypeScript 7 infers their type parameters from the unwrapped snapshot rather than from the root-wrapper union member. Co-Authored-By: Claude Opus 5.5 --- .changeset/typescript-7-compatibility-lane.md | 3 + CONTRIBUTING.md | 25 ++ package.json | 3 +- .../test/machine/Machine.test.ts | 6 +- pnpm-lock.yaml | 214 ++++++++++++++++++ pnpm-workspace.yaml | 1 + scripts/test-consumer.mjs | 16 +- tooling/typescript-7/package.json | 12 + 8 files changed, 275 insertions(+), 5 deletions(-) create mode 100644 .changeset/typescript-7-compatibility-lane.md create mode 100644 tooling/typescript-7/package.json diff --git a/.changeset/typescript-7-compatibility-lane.md b/.changeset/typescript-7-compatibility-lane.md new file mode 100644 index 00000000..853d812b --- /dev/null +++ b/.changeset/typescript-7-compatibility-lane.md @@ -0,0 +1,3 @@ +--- + +--- diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9d5aa4f3..41f7632b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -76,6 +76,31 @@ understands imports, re-exports, and dynamic imports, and enforces: The checker has executable fixture tests and runs as part of `pnpm check`. Add new rules only with a failing fixture that demonstrates the boundary. +## TypeScript compatibility + +The repository toolchain uses TypeScript 6. TypeDoc, tstyche, and the +repository scripts load its JavaScript compiler API, so the root `typescript` +dependency stays on 6.x. + +`pnpm check` also verifies the native TypeScript 7 compiler. The private +`tooling/typescript-7` workspace package pins it in its own `node_modules`, so +its `tsc` binary never replaces the TypeScript 6 `tsc` used by the root and the +publishable packages: + +- `pnpm typecheck:ts7` type-checks every package project and + `tsconfig.tests.json` without emitting. Run it after `pnpm typecheck` or + `pnpm build`, because package references resolve to the TypeScript 6 + declaration output. +- `pnpm test:consumer` compiles the packed consumer fixture with TypeScript 6 + and then with TypeScript 7. Set `TSGO_BIN` to an executable native compiler to + check another TypeScript 7 build. + +Type tests run only with TypeScript 6: tstyche 7.2 selects targets from +TypeScript 5.4 up to, but not including, 7.0, because TypeScript 7 does not +provide the in-process compiler API that tstyche uses. TypeScript 7 still +compiles the public types through the package projects and the runtime tests, +but type assertions are evaluated only with TypeScript 6. + ## API reference data `pnpm docs:api` generates an Effect-compatible TypeDoc dataset under diff --git a/package.json b/package.json index c35f0992..f12f3621 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "check:architecture": "node --test scripts/check-architecture.test.mjs && node scripts/check-architecture.mjs packages/effect-machine && node scripts/check-devtools-architecture.mjs packages/devtools", "check:ci": "node --test scripts/ci-changes.test.mjs scripts/effect-compatibility.test.mjs scripts/invoke-autocomplete.test.mjs scripts/release-contract.test.mjs scripts/runtime-performance-compatibility.test.mjs scripts/runtime-performance-regression.test.mjs", "typecheck": "pnpm --recursive --filter \"./packages/**\" run check && tsc -p tsconfig.tests.json", + "typecheck:ts7": "pnpm --dir tooling/typescript-7 run typecheck", "perf:types": "pnpm build && node scripts/type-performance.mjs", "perf:runtime": "pnpm build && node --expose-gc scripts/runtime-performance.mjs", "format": "dprint fmt", @@ -28,7 +29,7 @@ "react:pack-check": "node scripts/react-pack-check.mjs", "devtools:pack-check": "node scripts/devtools-pack-check.mjs", "oxlint-plugin:pack-check": "node scripts/oxlint-plugin-pack-check.mjs", - "check": "pnpm format:check && pnpm check:architecture && pnpm check:ci && pnpm docs:api:check && pnpm docs:site:check && pnpm typecheck && pnpm build && pnpm test && pnpm test:types && pnpm test:consumer && pnpm pack:check && pnpm react:pack-check && pnpm devtools:pack-check && pnpm oxlint-plugin:pack-check", + "check": "pnpm format:check && pnpm check:architecture && pnpm check:ci && pnpm docs:api:check && pnpm docs:site:check && pnpm typecheck && pnpm typecheck:ts7 && pnpm build && pnpm test && pnpm test:types && pnpm test:consumer && pnpm pack:check && pnpm react:pack-check && pnpm devtools:pack-check && pnpm oxlint-plugin:pack-check", "changeset": "changeset", "version-packages": "changeset version && dprint fmt", "release": "pnpm build && changeset publish" diff --git a/packages/effect-machine/test/machine/Machine.test.ts b/packages/effect-machine/test/machine/Machine.test.ts index 8c1a000d..97f16c34 100644 --- a/packages/effect-machine/test/machine/Machine.test.ts +++ b/packages/effect-machine/test/machine/Machine.test.ts @@ -33,7 +33,7 @@ const sendAndWaitForSnapshot = ( const assertStateSnapshot = ( actual: | Machine.Machine.AtomicSnapshot - | Machine.Machine.CompoundSnapshot<"", undefined, Machine.Machine.AtomicSnapshot>, + | Machine.Machine.CompoundSnapshot<"", undefined, NoInfer>>, path: Path, value: Value ) => { @@ -47,7 +47,7 @@ const assertStateSnapshot = ( const assertCompoundStateSnapshot = ( actual: | Machine.Machine.CompoundSnapshot - | Machine.Machine.CompoundSnapshot<"", undefined, Machine.Machine.CompoundSnapshot>, + | Machine.Machine.CompoundSnapshot<"", undefined, NoInfer>>, path: Path, value: Value, state: Child @@ -63,7 +63,7 @@ const assertCompoundStateSnapshot = ( const assertParallelStateSnapshot = ( actual: | Machine.Machine.ParallelSnapshot - | Machine.Machine.CompoundSnapshot<"", undefined, Machine.Machine.ParallelSnapshot>, + | Machine.Machine.CompoundSnapshot<"", undefined, NoInfer>>, path: Path, value: Value, states: States diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3c190228..81238ea5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -170,6 +170,12 @@ importers: specifier: 5.0.1 version: 5.0.1(@types/node@25.7.0)(jsdom@27.2.0)(vite@8.1.5(@types/node@25.7.0)(esbuild@0.27.7)(tsx@4.21.0)(yaml@2.9.0)) + tooling/typescript-7: + devDependencies: + typescript: + specifier: 7.0.2 + version: 7.0.2 + packages: '@acemir/cssom@0.9.31': @@ -986,6 +992,126 @@ packages: '@types/ws@8.18.2': resolution: {integrity: sha512-67MQl+fpWKVTT1NYdnmo3U4sc/xPo/zQBncVnI74qmQa0z/b+1g6iYqNmGCPbxO+zz2aklb08a0oHfegiVd0/w==} + '@typescript/typescript-aix-ppc64@7.0.2': + resolution: {integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [aix] + + '@typescript/typescript-darwin-arm64@7.0.2': + resolution: {integrity: sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [darwin] + + '@typescript/typescript-darwin-x64@7.0.2': + resolution: {integrity: sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [darwin] + + '@typescript/typescript-freebsd-arm64@7.0.2': + resolution: {integrity: sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [freebsd] + + '@typescript/typescript-freebsd-x64@7.0.2': + resolution: {integrity: sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [freebsd] + + '@typescript/typescript-linux-arm64@7.0.2': + resolution: {integrity: sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [linux] + + '@typescript/typescript-linux-arm@7.0.2': + resolution: {integrity: sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==} + engines: {node: '>=16.20.0'} + cpu: [arm] + os: [linux] + + '@typescript/typescript-linux-loong64@7.0.2': + resolution: {integrity: sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==} + engines: {node: '>=16.20.0'} + cpu: [loong64] + os: [linux] + + '@typescript/typescript-linux-mips64el@7.0.2': + resolution: {integrity: sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==} + engines: {node: '>=16.20.0'} + cpu: [mips64el] + os: [linux] + + '@typescript/typescript-linux-ppc64@7.0.2': + resolution: {integrity: sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [linux] + + '@typescript/typescript-linux-riscv64@7.0.2': + resolution: {integrity: sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==} + engines: {node: '>=16.20.0'} + cpu: [riscv64] + os: [linux] + + '@typescript/typescript-linux-s390x@7.0.2': + resolution: {integrity: sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==} + engines: {node: '>=16.20.0'} + cpu: [s390x] + os: [linux] + + '@typescript/typescript-linux-x64@7.0.2': + resolution: {integrity: sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [linux] + + '@typescript/typescript-netbsd-arm64@7.0.2': + resolution: {integrity: sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [netbsd] + + '@typescript/typescript-netbsd-x64@7.0.2': + resolution: {integrity: sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [netbsd] + + '@typescript/typescript-openbsd-arm64@7.0.2': + resolution: {integrity: sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [openbsd] + + '@typescript/typescript-openbsd-x64@7.0.2': + resolution: {integrity: sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [openbsd] + + '@typescript/typescript-sunos-x64@7.0.2': + resolution: {integrity: sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [sunos] + + '@typescript/typescript-win32-arm64@7.0.2': + resolution: {integrity: sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [win32] + + '@typescript/typescript-win32-x64@7.0.2': + resolution: {integrity: sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [win32] + '@vitest/mocker@5.0.1': resolution: {integrity: sha512-6K1DoBNAPGvuOcSsGA4D6x+5zEEff/KmOOP3uetT2TrGpVfI+HRHRnJJfKi5ib/g1vx8IYHQD8s0pbJz8WQI7Q==} peerDependencies: @@ -1706,6 +1832,11 @@ packages: engines: {node: '>=14.17'} hasBin: true + typescript@7.0.2: + resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==} + engines: {node: '>=16.20.0'} + hasBin: true + uc.micro@2.1.0: resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} @@ -2542,6 +2673,66 @@ snapshots: dependencies: '@types/node': 25.7.0 + '@typescript/typescript-aix-ppc64@7.0.2': + optional: true + + '@typescript/typescript-darwin-arm64@7.0.2': + optional: true + + '@typescript/typescript-darwin-x64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-x64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm@7.0.2': + optional: true + + '@typescript/typescript-linux-loong64@7.0.2': + optional: true + + '@typescript/typescript-linux-mips64el@7.0.2': + optional: true + + '@typescript/typescript-linux-ppc64@7.0.2': + optional: true + + '@typescript/typescript-linux-riscv64@7.0.2': + optional: true + + '@typescript/typescript-linux-s390x@7.0.2': + optional: true + + '@typescript/typescript-linux-x64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-sunos-x64@7.0.2': + optional: true + + '@typescript/typescript-win32-arm64@7.0.2': + optional: true + + '@typescript/typescript-win32-x64@7.0.2': + optional: true + '@vitest/mocker@5.0.1(vite@8.1.5(@types/node@25.7.0)(esbuild@0.27.7)(tsx@4.21.0)(yaml@2.9.0))': dependencies: '@jridgewell/trace-mapping': 0.3.31 @@ -3225,6 +3416,29 @@ snapshots: typescript@6.0.3: {} + typescript@7.0.2: + optionalDependencies: + '@typescript/typescript-aix-ppc64': 7.0.2 + '@typescript/typescript-darwin-arm64': 7.0.2 + '@typescript/typescript-darwin-x64': 7.0.2 + '@typescript/typescript-freebsd-arm64': 7.0.2 + '@typescript/typescript-freebsd-x64': 7.0.2 + '@typescript/typescript-linux-arm': 7.0.2 + '@typescript/typescript-linux-arm64': 7.0.2 + '@typescript/typescript-linux-loong64': 7.0.2 + '@typescript/typescript-linux-mips64el': 7.0.2 + '@typescript/typescript-linux-ppc64': 7.0.2 + '@typescript/typescript-linux-riscv64': 7.0.2 + '@typescript/typescript-linux-s390x': 7.0.2 + '@typescript/typescript-linux-x64': 7.0.2 + '@typescript/typescript-netbsd-arm64': 7.0.2 + '@typescript/typescript-netbsd-x64': 7.0.2 + '@typescript/typescript-openbsd-arm64': 7.0.2 + '@typescript/typescript-openbsd-x64': 7.0.2 + '@typescript/typescript-sunos-x64': 7.0.2 + '@typescript/typescript-win32-arm64': 7.0.2 + '@typescript/typescript-win32-x64': 7.0.2 + uc.micro@2.1.0: {} undici-types@7.21.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index fa490a1f..7e5a3d7b 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,5 +1,6 @@ packages: - "packages/*" + - "tooling/*" overrides: effect: 4.0.0 diff --git a/scripts/test-consumer.mjs b/scripts/test-consumer.mjs index 9e70a503..cf688cce 100644 --- a/scripts/test-consumer.mjs +++ b/scripts/test-consumer.mjs @@ -51,12 +51,26 @@ try { [join(repositoryRoot, "node_modules", "typescript", "bin", "tsc"), "-p", join(consumer, "tsconfig.json")], { cwd: consumer } ) + // The consumer must also compile with the native TypeScript 7 compiler pinned + // by tooling/typescript-7. TSGO_BIN selects another native compiler binary. if (process.env.TSGO_BIN !== undefined) { run(process.env.TSGO_BIN, ["-p", join(consumer, "tsconfig.json")], { cwd: consumer }) + } else { + run( + process.execPath, + [ + join(repositoryRoot, "tooling", "typescript-7", "node_modules", "typescript", "bin", "tsc"), + "-p", + join(consumer, "tsconfig.json") + ], + { cwd: consumer } + ) } run(process.execPath, [join(consumer, "runtime.mjs")], { cwd: consumer }) - console.log("packed root, reactivity, cluster, and testing entrypoints passed strict consumer validation") + console.log( + "packed root, reactivity, cluster, and testing entrypoints passed strict consumer validation with TypeScript 6 and 7" + ) } finally { await rm(destination, { recursive: true, force: true }) } diff --git a/tooling/typescript-7/package.json b/tooling/typescript-7/package.json new file mode 100644 index 00000000..07a4987f --- /dev/null +++ b/tooling/typescript-7/package.json @@ -0,0 +1,12 @@ +{ + "name": "@typeonce/effect-machine-typescript-7", + "private": true, + "type": "module", + "description": "Pins the native TypeScript 7 compiler for the compatibility lane without replacing the TypeScript 6 toolchain.", + "scripts": { + "typecheck": "tsc -p ../../packages/effect-machine/tsconfig.json --noEmit && tsc -p ../../packages/effect-machine-react/tsconfig.json --noEmit && tsc -p ../../packages/oxlint-plugin/tsconfig.json --noEmit && tsc -p ../../packages/devtools/tsconfig.json && tsc -p ../../tsconfig.tests.json" + }, + "devDependencies": { + "typescript": "7.0.2" + } +}