If you worked through TypeScript for QA, you already installed TypeScript in a fresh folder. This lesson is different: you're installing TypeScript into an existing JavaScript project that is already running tests. The goal is to add TypeScript without breaking anything — the existing tests must keep running at every step.
Step 1: Install TypeScript
Open your existing project folder in a terminal. Install TypeScript as a development dependency:
npm install --save-dev typescript @types/node@types/node gives you type definitions for Node.js built-ins — process.env, Buffer, path, fs. You almost certainly need it even if your tests run in a browser, because most Cypress and Playwright config files run in Node.
Check the install worked:
npx tsc --version
# Version 5.x.xDo not install TypeScript globally (npm install -g typescript). Different projects pin different TypeScript versions, and a global install creates subtle mismatches. --save-dev keeps it scoped to this project.
Step 2: Create tsconfig.json
Run:
npx tsc --initThis generates a tsconfig.json at your project root with most options listed but commented out. You are going to replace it with a migration-friendly configuration.
Step 3: Migration-friendly tsconfig.json
The default tsconfig.json generated by --init is configured for a greenfield TypeScript project. For a migration, you need different defaults — permissive enough that existing JavaScript continues to compile, strict enough that TypeScript is actually useful on the files you convert.
Replace the generated file with this:
{
"compilerOptions": {
"target": "ES2022",
"module": "commonjs",
"allowJs": true,
"checkJs": false,
"strict": false,
"noImplicitAny": false,
"esModuleInterop": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"forceConsistentCasingInFileNames": true
},
"include": ["**/*.ts", "**/*.js"],
"exclude": ["node_modules", "dist", "cypress/screenshots", "cypress/videos"]
}The two critical settings for migration:
allowJs: true— the TypeScript compiler processes.jsfiles alongside.tsfiles. Without this, TypeScript only sees files you've already renamed.checkJs: false—.jsfiles are included but not type-checked. They compile, but no errors are reported for them. This keeps the existing project green from day one.
The two settings you are deliberately leaving permissive:
strict: false— turns off the full strict suite. You'll enable these flags incrementally in Lesson 3 of this chapter.noImplicitAny: false— parameters without explicit types are silentlyany. You'll turn this on after converting your first batch of files.
Step 4: Add type-check scripts
In package.json:
{
"scripts": {
"type-check": "tsc --noEmit",
"type-check:watch": "tsc --noEmit --watch"
}
}--noEmit tells TypeScript to check types without writing any output files. This is what you want in a CI check — you're not compiling to a dist/ folder, you're just verifying the types are correct.
Step 5: Verify everything is green
Run:
npm run type-checkWith allowJs: true, checkJs: false, and strict: false, this should produce zero errors even though the project is still entirely JavaScript. If you see errors, they are from the node_modules or generated files leaking into the compiler's scope — check your exclude list.
Step 1 of 5
Install TypeScript
npm install --save-dev typescript @types/node — scoped to the project, not global. Verify with npx tsc --version.
The outDir question
You may notice the migration config above has no outDir. That's intentional. During migration, most test runners (Cypress, Playwright, Jest with ts-jest) compile TypeScript themselves — they don't use your tsconfig.json's output directory. Setting outDir would cause confusion if someone runs npx tsc and ends up with a dist/ folder of compiled test files that nobody uses.
If you have utility scripts or a shared library that needs a real build step, add outDir to a separate tsconfig.build.json and keep the base config clean.
What about Cypress-specific config?
Cypress looks for a tsconfig.json in the cypress/ directory first. If it doesn't find one, it uses the project root. For a migration, the root config with allowJs: true is sufficient to start — Cypress will pick it up.
Once you've converted most Cypress files, you can add a cypress/tsconfig.json that extends the root config and adds Cypress-specific type declarations:
{
"extends": "../tsconfig.json",
"compilerOptions": {
"types": ["cypress", "node"]
},
"include": ["**/*.ts", "**/*.js"]
}The "types": ["cypress", "node"] line restricts auto-loaded type packages to just Cypress and Node, preventing browser DOM types from conflicting with Cypress's own DOM definitions.
⚠️ Common mistakes
- Running
npx tscwithout--noEmitand being surprised by adist/folder. During migration, always usenpm run type-check(which passes--noEmit), not barenpx tsc. Adddist/to.gitignorejust in case. - Not excluding screenshot and video directories. Cypress writes screenshots and videos to
cypress/screenshotsandcypress/videos. If these directories contain JavaScript files, TypeScript will try to include them. Add both toexclude. - Forgetting
resolveJsonModule: true. If your tests import fixture files withimport data from "./fixtures/users.json", TypeScript needs this option to parse the import. Without it, you'll seeCannot find module './fixtures/users.json'errors as soon as you start converting test files.
🎯 Practice task
Add TypeScript to your JavaScript test project from the JavaScript for QA course, or clone a small Cypress or Playwright JavaScript starter.
- Run
npm install --save-dev typescript @types/node. - Run
npx tsc --initand then replace the generatedtsconfig.jsonwith the migration-friendly config from this lesson. - Add the
type-checkscript topackage.json. - Run
npm run type-check. Confirm it exits with zero errors. - Stretch: deliberately introduce a mistake in the tsconfig — set
includeto["src/**/*.ts"]without a matchingsrc/directory — and observe what happens. Then restore the correct include pattern. Understanding how the compiler resolves files saves hours of debugging in real migrations.
Once type-check passes with zero errors on an all-JavaScript codebase, you have a stable base to start converting files. The next lesson covers the allowJs and checkJs settings in depth.