Careeroza
Migrating a JavaScript Project to TypeScript
Step by Step
- Install
typescriptand@types/*for your libraries; add atsconfig.jsonwith"allowJs": trueand"strict": falseto start. - Make the build work with mixed
.js/.tsfiles. Addtsc --noEmitto CI. - Turn on
"checkJs": trueor add// @ts-checkto important JS files to get errors from JSDoc and inference. - Rename files to
.tsone folder at a time, starting with leaf modules (utils, constants, types) that others depend on. - Type the boundaries first: API responses, database models, function parameters of shared modules.
- Enable strict flags one by one (
noImplicitAny, thenstrictNullChecks, ...). Use// @ts-expect-errorwith a TODO for hard cases, never blanketany. - Finally set
"allowJs": falseand"strict": true.
ts-expect-error vs ts-ignore
Example
@ts-expect-error suppresses the next line's error but itself becomes an error (TS2578) once the problem is fixed, so suppressions do not rot. @ts-ignore stays silent forever.
function total(prices: number[]): number {
return prices.reduce((a, b) => a + b, 0);
}
// @ts-expect-error legacy caller still passes strings, fix in JIRA-123
total(["10", "20"]);
// @ts-expect-error this line is actually fine, so the directive itself is reported
total([10, 20]);Compiler output (tsc)
Line 8: error TS2578: Unused '@ts-expect-error' directive.
Migration Helpers
npx ts-migrate(Airbnb) renames files and addsany/@ts-expect-errorautomatically so the build is green on day one; then you tighten gradually.- Track progress with
type-coverage(percentage of identifiers that are notany). - Large companies (Airbnb, Slack, Stripe, Bloomberg) migrated millions of lines this way, team by team.