feat: support TypeScript 7 for spec preprocessing#34277
Conversation
TypeScript 7 (the native compiler) ships without the JavaScript compiler API, so ts-loader crashes when transpiling TypeScript spec and support files. Detect TypeScript 7+ in the webpack batteries-included preprocessor and transpile those files with Babel (@babel/preset-typescript, plus legacy decorators + babel-plugin-transform-typescript-metadata to preserve emitDecoratorMetadata) instead of ts-loader. TypeScript <= 6 is unchanged. Also widen the component testing setup wizard's accepted TypeScript range to include 7.x. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
cypress
|
||||||||||||||||||||||||||||
| Project |
cypress
|
| Branch Review |
mschile/focused-germain-deffe6
|
| Run status |
|
| Run duration | 13m 31s |
| Commit |
|
| Committer | Matthew Schile |
| View all properties for this run ↗︎ | |
| Test results | |
|---|---|
|
|
0
|
|
|
0
|
|
|
0
|
|
|
0
|
|
|
52
|
| View all changes introduced in this branch ↗︎ | |
Warning
No Report: Something went wrong and we could not generate a report for the Application Quality products.
AtofStryker
left a comment
There was a problem hiding this comment.
The preprocessor change looks good to me — babel transpile-only is the right call given TS 7 shipped without a compiler API, and the test coverage on that path is solid (including the decorator-metadata ordering assertions).
Approving with one ask, which is the only thing I'm concerned about here: a vite + typescript@7 component testing system test added to this PR. Vite CT is the one CT path that works with TS 7 today — @cypress/vite-dev-server never touches the TS compiler API, and config-file loading uses our bundled tsx/esbuild — but we have zero coverage proving it, and the wizard change in this PR is now telling users TS 7 is good for CT. A fixture modeled on react-vite-ts-configured (bumped to typescript@7.x, with a .tsx spec) plus a block in component_testing_spec.ts alongside the existing one would lock it in.
For context, where the other CT paths stand with typescript@7 — none of these need anything in this PR:
- Webpack (react/vue/svelte): nothing for us to do — we source the user's own webpack config and ship no TS loaders ourselves. If their config uses ts-loader it breaks with typescript@7, but it breaks identically outside Cypress, and whatever fix they adopt flows through to us since we consume their config.
- Angular: broken upstream —
@ngtools/webpackneedsts.createProgram/ts.sys, and Angular 22 pinstypescript >=6.0 <6.1(angular/angular#69704), so no Angular project builds with TS 7 anywhere today and there's nothing we could test against. - Next:
next buildaborts with typescript@7 installed (vercel/next.js#95490); fixed only behindexperimental.useTypeScriptCliin the 16.3 preview. Same story.
On the wizard widening: I'm good keeping it. We have no way to know when Angular/Next will ship TS 7 support, and their breakage is upstream of us — we can deal with it if/when it surfaces. Allowing TS 7 for the paths that work beats holding the whole range back on frameworks we can't control.
One small test suggestion on the preprocessor itself: the decorator tests cover a class decorator + constructor parameter property, but not a decorated class field (@Input() foo: string / @Column() name: string style), which is the pattern most decorator users actually hit and the quirkiest combo with plugin-transform-class-properties. Worth adding while the fixtures are fresh.
Address review feedback on #34277: - Add a decorated class field case (property decorator + class-properties) to the preprocessor decorator-metadata fixture, the quirkiest combo for babel. - Add a react + vite + typescript@7 component testing system test to lock in the one CT bundler path that works with TypeScript 7. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Consolidate the vite + typescript@7 component testing coverage into the existing react-vite-ts-configured project (bumped to typescript@7) rather than a near-duplicate fixture. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Split the changelog entry so the setup wizard note is its own sentence. - Drop the ts-loader-specific rationale from a shared comment (may change). - Simplify the TypeScript 7 e2e describe title. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Additional details
TypeScript 7 (the native/Go compiler, GA'd 2026-07-08) ships an npm package with no JavaScript compiler API —
ts.sys,createProgram,transpileModule, etc. no longer exist.@cypress/webpack-batteries-included-preprocessorresolves the project'stypescriptand hands it tots-loaderas the compiler, so on atypescript@7project every spec crashes before a test runs:What this changes:
@cypress/webpack-batteries-included-preprocessor— When the resolved TypeScript version is>= 7.0.0,.ts/.tsxspec and support files are transpiled withbabel-loader+@babel/preset-typescriptinstead ofts-loader. This matches the transpile-only behavior we already had (ts-loaderran withtranspileOnly: true, so no type-checking happened at bundle time before or after). TypeScript<= 6is completely unchanged and still usests-loaderwith the project's compiler.emitDecoratorMetadataparity —ts.transpileModule(whattranspileOnlycalls) emits decorator metadata, so the babel path adds@babel/plugin-proposal-decorators(legacy) +babel-plugin-transform-typescript-metadatato preserve it.tsconfigpathsaliases continue to work (resolved bytsconfig-paths-webpack-plugin, which reads the tsconfig JSON and needs no compiler API).WIZARD_DEPENDENCY_TYPESCRIPT.minVersionwidened to^5.0.0 || ^6.0.0 || ^7.0.0so component-testing onboarding no longer blockstypescript@7projects.Known behavioral differences under TypeScript 7 (all scoped to TS 7+; none affect TS ≤ 6):
tsconfigcompilerOptionsno longer drive spec output — babel uses a fixed config (preset-env targeting Chrome 64, CommonJS) plus classicpreset-react. The observable case is a.tsxe2e spec using the automatic JSX runtime ("jsx": "react-jsx"): babel emitsReact.createElement, so React must be in scope. This already matches how.jsxe2e specs behave in this preprocessor; TSX in e2e specs is rare (component specs go through the framework dev server, not this path).experimentalDecorators+emitDecoratorMetadata); standard TC39 decorators are not supported on this path. Because babel emits an unguardedReflect.metadata(...)call, decorator-metadata code requiresreflect-metadatato be loaded at runtime (projects using metadata already do this).@babel/preset-typescriptmust support new TypeScript syntax as it ships. TS 7.0 adds no new syntax, so there's no gap today.Implementation note: the new babel deps use caret ranges, which pulls a monorepo-wide
@babel/*7.28 → 7.29 bump inyarn.lock(within existing semver ranges).Note
Medium Risk
Swapping the transpiler for TS 7+ can change JSX/decorator output vs tsconfig-driven ts-loader; risk is mitigated by version gating and broad tests but affects all TS7 e2e preprocessing.
Overview
Adds TypeScript 7 support for Cypress e2e spec/support preprocessing and widens the component-testing wizard to accept
typescript@7.Because TypeScript 7’s npm package no longer exposes the compiler API that
ts-loaderneeds,@cypress/webpack-batteries-included-preprocessornow detects resolved TypeScript>= 7and transpiles.ts/.tsxwithbabel-loader+@babel/preset-typescriptinstead ofts-loader, while keeping the prior transpile-only behavior for TS ≤ 6. Babel options are centralized ingetBabelLoaderOptions, with legacy decorators andbabel-plugin-transform-typescript-metadataon the TS path to preserveemitDecoratorMetadataparity;tsconfig-paths-webpack-pluginbehavior is unchanged.WIZARD_DEPENDENCY_TYPESCRIPT.minVersionnow includes^7.0.0. Coverage adds unit/e2e tests for the TS 7 branch, ats-proj-7system fixture (including decorator metadata), and bumpsreact-vite-ts-configuredto TypeScript 7 for component testing.Reviewed by Cursor Bugbot for commit 570e364. Bugbot is set up for automated code reviews on this repo. Configure here.
Steps to test
The
AtofStryker/typescript-7-cypressminimal repro (an untouchedcypress openscaffold + atypescript@7tsconfig) reproduces the original crash ondevelop. To validate:typescript@7installed, run an e2e spec written in TypeScript:npx cypress run --spec cypress/e2e/spec.cy.ts. It should compile and run instead of failing with thefileExistscrash.yarn workspace @cypress/webpack-batteries-included-preprocessor test(exercises the TS 7 branch against a realtypescript@7install via atypescript-v7alias, including decorator metadata).yarn workspace @packages/scaffold-config test -- dependencies.spec.tsts-proj-7fixture):cd system-tests && node ./scripts/run.js --glob-in-dir="typescript_spec_support" -- --browser electronHow has the user experience changed?
Projects that upgrade to TypeScript 7 can now compile and run their TypeScript specs. Previously, every TypeScript spec failed to compile (0 tests executed) with a

Cannot read properties of undefined (reading 'fileExists')error. No change for projects on TypeScript 6 or earlier.Before:
After:

PR Tasks
cypress-documentation? cypress-io/cypress-documentation#6696 (base:release/15.19.0)type definitions?