YouTip LogoYouTip

Ts Migration

## Migrating from JavaScript to TypeScript Migrating an existing JavaScript codebase to TypeScript does not have to be an all-or-nothing process. TypeScript is designed to support **gradual migration**, allowing you to convert your project file by file, module by module, while keeping your application functional throughout the transition. This guide outlines a structured, step-by-step strategy to migrate your JavaScript projects to TypeScript safely and efficiently. --- ## Migration Strategy A successful migration typically follows these four phases: 1. **Initialize the Environment**: Add a `tsconfig.json` file to configure the compiler. 2. **Enable Coexistence**: Allow JavaScript and TypeScript files to coexist using `allowJs`. 3. **Convert Files Gradually**: Rename `.js` files to `.ts` (or `.jsx` to `.tsx`) one by one. 4. **Tighten Type Safety**: Gradually enable strict type-checking options as the migration nears completion. --- ## Configuring `tsconfig.json` The first step is to initialize a TypeScript configuration file. Run `npx tsc --init` in your project root to generate a `tsconfig.json`. During the initial phase of migration, you should use a **loose configuration** so the compiler does not throw errors on your existing JavaScript code. ### Initial Loose Configuration ```json { "compilerOptions": { // Target modern ECMAScript features "target": "ES2020", "module": "commonjs", // Initial phase: Loose type checking "strict": false, "noImplicitAny": false, "strictNullChecks": false, "skipLibCheck": true, // Allow JS files to coexist and be compiled "allowJs": true, "checkJs": false, // Output and source directories "outDir": "./dist", "rootDir": "./src" }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"] } ``` --- ## Phased Strictness: Tightening Type Checks As you convert more files to TypeScript, you should gradually enable stricter compiler flags. This ensures your code benefits from TypeScript's robust type safety without overwhelming you with thousands of errors all at once. ### Phase 1: Basic Migration (Loose) Focus on converting file extensions and resolving module import/export issues. ```json { "compilerOptions": { "strict": false, "noImplicitAny": false } } ``` ### Phase 2: Moderate Type Checking Enforce explicit types and handle potential `null` or `undefined` values. ```json { "compilerOptions": { "strict": true, "noImplicitAny": true, "strictNullChecks": true } } ``` ### Phase 3: Fully Strict Production Enable the complete suite of strict checks for maximum type safety. ```json { "compilerOptions": { "strict": true, "noImplicitAny": true, "strictNullChecks": true, "strictFunctionTypes": true, "strictPropertyInitialization": true } } ``` --- ## Using JSDoc for Type Annotations in JavaScript You do not need to rename a file to `.ts` immediately to start type-checking it. You can use **JSDoc comments** in your existing `.js` files. The TypeScript compiler reads these comments to infer types. ### Example: `utils.js` ```javascript /** * Adds two numbers together. * @param {number} a * @param {number} b * @returns {number} */ function add(a, b) { return a + b; } /** * @typedef {Object} User * @property {number} id * @property {string} name * @property {string} email */ /** * Fetches a user by their ID. * @param {number} id * @returns {Promise} */ function getUser(id) { return fetch(`/api/users/${id}`).then(r => r.json()); } ``` **Result:** TypeScript-compatible IDEs (like VS Code) will read these JSDoc annotations and provide autocomplete, parameter hints, and type-checking directly inside your JavaScript files. --- ## Creating Type Declaration Files (`.d.ts`) When migrating, you might use third-party JavaScript libraries or internal legacy modules that lack type definitions. You can write custom type declaration files (`.d.ts`) to describe their APIs to TypeScript. ### Example: `src/types/my-module.d.ts` ```typescript declare module "my-module" { export function doSomething(param: string): void; export class MyClass { constructor(options: { name: string }); name: string; } } ``` --- ## Working with the `declare` Keyword The `declare` keyword is used to define variables, functions, or namespaces that exist in the global scope (e.g., injected by a `