مهاجرت (Migration)
می خواهی از جاوااسکریپت به تایپ اسکریپت کوچ کنی؟ «مهاجرت (Migration)» یعنی تغییر آرام و برنامه ریزی شده. با این کار، نگه داری راحت تر می شود و خطاها زودتر می افتند.
فاز آماده سازی
اول پروژه ات را بسنج. سپس مسیر ساخت و وابستگی ها را ثبت کن. همچنین، فایل های اعلان نوع .d.ts را بررسی کن. در پایان، مسیرهای حیاتی را مشخص کن.
شاخه گیت برای مهاجرت
# Create a new branch for the migration\ngit checkout -b typescript-migration\n\n# Commit your current state\ngit add .\n\ngit commit -m "Pre-TypeScript migration state"\n
پیکربندی پایه
نصب تایپ اسکریپت
# Install TypeScript as a dev dependency\nnpm install --save-dev typescript @types/node\n
ساخت tsconfig.json
{\n "compilerOptions": {\n "target": "ES2020",\n "module": "commonjs",\n "strict": true,\n "esModuleInterop": true,\n "skipLibCheck": true,\n "forceConsistentCasingInFileNames": true,\n "outDir": "./dist",\n "rootDir": "./src"\n },\n "include": ["src/**/*"],\n "exclude": ["node_modules"]\n}\n
نکته: مقدار target را با حداقل پلتفرم های هدف هماهنگ کن.
رویکردهای مهاجرت
مهاجرت تدریجی
{\n "compilerOptions": {\n "allowJs": true,\n "checkJs": true\n }\n}\n
نکته: برای پروژه های بزرگ، تدریجی بهترین انتخاب است.
همه چیز یک جا
# Rename all JS files to TS\nfind src -name "*.js" -exec sh -c 'mv "$0" "${0%.js}.ts"' {} \;\n
مهاجرت گام به گام
پیکربندی پیشنهادی برای شروع
{\n "compilerOptions": {\n "target": "ES2020",\n "module": "commonjs",\n "strict": true,\n "esModuleInterop": true,\n "skipLibCheck": true,\n "forceConsistentCasingInFileNames": true,\n "outDir": "./dist",\n "rootDir": "./src",\n "allowJs": true,\n "checkJs": true,\n "noEmit": true\n },\n "include": ["src/**/*"],\n "exclude": ["node_modules", "dist"]\n}\n
فعال سازی بررسی نوع در JS
// @ts-check\n\n/** @type {string} */\nconst name = 'John';\n\n// TypeScript will catch this error\nname = 42;\n
نکته: برای بی اثرکردن موقت، از // @ts-ignore تنها در ضرورت استفاده کن.
تغییر پسوند فایل ها
# Rename a single file\nmv src/utils/helpers.js src/utils/helpers.ts\n\n# Or bulk rename carefully\nfind src/utils -name "*.js" -exec sh -c 'mv "$0" "${0%.js}.ts"' {} \;\n
افزودن حاشیه نویسی نوع
// Before\nfunction add(a, b) {\n return a + b;\n}\n\n// After\nfunction add(a: number, b: number): number {\n return a + b;\n}\n\n// With interface\ninterface User {\n id: number;\n name: string;\n email?: string;\n}\n\nfunction getUser(id: number): User {\n return { id: id, name: 'John Doe' };\n}\n
به روزرسانی اسکریپت های ساخت
{\n "scripts": {\n "build": "tsc",\n "dev": "tsc --watch",\n "test": "jest"\n }\n}\n
ابزارهای کمک کننده
ts-migrate
npx ts-migrate-full .\n
TypeStat
npx typestat --init\n
بسته های @types
npm install --save-dev @types/react @types/node\n
چالش های رایج و راه حل
ویژگی های پویا
// Before\nconst user = {};\nuser.name = 'John';\n
با امضای ایندکس یا Type Assertion مشکل را حل کن.
// Option 1: Index signature\ninterface User {\n [key: string]: any;\n}\nconst u1: User = {};\nu1.name = 'John';\n\n// Option 2: Type assertion\nconst u2 = {} as { name: string };\nu2.name = 'John';\n
بستن this در کال بک ها
class Counter {\n count = 0;\n increment() {\n setTimeout(() => {\n this.count++;\n }, 1000);\n }\n}\n
ادامه مسیر
برای تایپ دهی در JS ببین JSDoc در پروژه های JS. برای مدیریت خطا ادامه بده به مدیریت خطا. همچنین الگوهای فراگیر را در دکوراتورها ببین.
جمع بندی سریع
- با پیکربندی درست شروع کن.
- تدریجی مهاجرت کن، نه شتاب زده.
allowJsوcheckJsرا فعال کن.- پسوندها را آرام تغییر بده.
- ابزارها را هوشمندانه استفاده کن.