JavaScript'ten TypeScript'e Migration Rehberi

JavaScript'ten TypeScript'e Migration Rehberi
Mevcut bir JavaScript projesini TypeScript'e taşımak, kod kalitesini artıran ve hataları derleme zamanında yakalayan stratejik bir karardır. Ancak bu geçiş, doğru planlama ve kademeli uygulama gerektirir. Bu rehberde JavaScript projenizi TypeScript'e adım adım nasıl migrate edeceğinizi, yapılandırma ayarlarını, sık karşılaşılan sorunları ve en iyi pratikleri inceleyeceğiz.
Migration Stratejileri
TypeScript'e geçiş için üç temel strateji vardır:
- Kademeli geçiş (Önerilen):
allowJs: trueile başlayın, dosya dosya dönüştürün - Tam geçiş: Tüm dosyaları bir seferde dönüştürün (küçük projeler için)
- Yeni modül stratejisi: Yeni yazılan tüm kodlar TypeScript, eski kod zamanla dönüştürülür
Adım 1: TypeScript ve Bağımlılıkları Yükleme
# TypeScript ve gerekli araçları yükle
npm install -D typescript @types/node
# React projesi için
npm install -D @types/react @types/react-dom
# Kullandığınız kütüphaneler için tip tanımları
npm install -D @types/express @types/lodash @types/jest
# ts-node (Node.js projeleri için)
npm install -D ts-node
Adım 2: tsconfig.json Oluşturma
Migration için uygun başlangıç yapılandırması:
// tsconfig.json
{
"compilerOptions": {
// Migration başlangıç ayarları (gevşek)
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"outDir": "./dist",
"rootDir": "./src",
// JavaScript dosyalarına izin ver
"allowJs": true,
"checkJs": false,
// Başlangıçta strict kapalı
"strict": false,
"noImplicitAny": false,
// Module resolution
"moduleResolution": "node",
"esModuleInterop": true,
"resolveJsonModule": true,
"isolatedModules": true,
"forceConsistentCasingInFileNames": true,
// Source map
"sourceMap": true,
"declaration": true,
// Path alias
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
allowJs: true ayarı, TypeScript derleyicisinin .js dosyalarını da işlemesini sağlar. Bu sayede .ts ve .js dosyaları bir arada bulunabilir.
Adım 3: Dosya Uzantılarını Dönüştürme
Dosyaları kademeli olarak .js'den .ts'ye (veya .jsx'den .tsx'ye) değiştirin:
# Toplu dosya uzantısı değiştirme (Linux/Mac)
find src -name "*.js" -exec bash -c 'mv "$0" "${0%.js}.ts"' {} \;
find src -name "*.jsx" -exec bash -c 'mv "$0" "${0%.jsx}.tsx"' {} \;
# Veya kademeli olarak öncelik sırasına göre:
# 1. Utility ve helper dosyaları
# 2. Type tanım dosyaları
# 3. Service ve API katmanı
# 4. Bileşenler (React)
# 5. Sayfa ve route dosyaları
Adım 4: Yaygın Dönüşüm Kalıpları
Fonksiyon Parametreleri
// JavaScript
function calculateTotal(items, taxRate) {
return items.reduce((sum, item) => sum + item.price * item.quantity, 0)
* (1 + taxRate);
}
// TypeScript
interface CartItem {
id: string;
name: string;
price: number;
quantity: number;
}
function calculateTotal(items: CartItem[], taxRate: number): number {
return items.reduce((sum, item) => sum + item.price * item.quantity, 0)
* (1 + taxRate);
}
Object Shapes ve Interface
// JavaScript
function createUser(name, email, role) {
return { id: Date.now().toString(), name, email, role, createdAt: new Date() };
}
// TypeScript
interface User {
id: string;
name: string;
email: string;
role: 'admin' | 'user' | 'editor';
createdAt: Date;
}
type CreateUserInput = Pick<User, 'name' | 'email' | 'role'>;
function createUser({ name, email, role }: CreateUserInput): User {
return {
id: Date.now().toString(),
name,
email,
role,
createdAt: new Date(),
};
}
API Response Tipleri
// JavaScript
async function fetchPosts() {
const res = await fetch('/api/posts');
const data = await res.json();
return data;
}
// TypeScript
interface Post {
id: number;
title: string;
body: string;
userId: number;
}
interface ApiResponse<T> {
data: T;
total: number;
page: number;
}
async function fetchPosts(): Promise<ApiResponse<Post[]>> {
const res = await fetch('/api/posts');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json() as Promise<ApiResponse<Post[]>>;
}
Adım 5: Strict Mode'a Kademeli Geçiş
Migration tamamlandıktan sonra strict ayarları kademeli olarak etkinleştirin:
// tsconfig.json - Kademeli strict geçiş
{
"compilerOptions": {
// Aşama 1: Temel kontroller
"noImplicitAny": true,
"strictNullChecks": false,
"strictFunctionTypes": false,
// Aşama 2: Null kontrolleri
// "strictNullChecks": true,
// Aşama 3: Tam strict
// "strict": true,
// Aşama 4: Ek kontroller
// "noUncheckedIndexedAccess": true,
// "exactOptionalPropertyTypes": true,
}
}
strictNullChecks: true etkinleştirildiğinde en fazla hata alacağınız ayardır. Her değerin null veya undefined olabileceği yerlerde kontrol eklemeniz gerekir.
Geçici Çözümler ve Tip Bastırma
Migration sırasında hızlı ilerleme için geçici tip bastırma yöntemleri:
// @ts-ignore: Bir sonraki satırdaki hatayı bastırır
// @ts-ignore
const value = someUntypedFunction();
// @ts-expect-error: Hata beklenir (hata yoksa uyarı verir, daha güvenli)
// @ts-expect-error Migration sırasında geçici
const result = legacyFunction(data);
// any ile geçici tip atama (kaçınılmalı)
const data: any = complexLegacyObject;
// unknown ile daha güvenli geçici tip
const response: unknown = await legacyApiCall();
if (isValidResponse(response)) {
// artık tip güvenli
}
@ts-ignore yerine @ts-expect-error kullanın. Eğer alttaki satırdaki hata düzeltilirse, @ts-expect-error size uyarı verir ve gereksiz bastırmaları temizlemenizi hatırlatır.
JSDoc ile Aşamalı Tipleme
Dosyayı .ts'ye dönüştürmeden JSDoc ile tip bilgisi ekleyebilirsiniz:
// utils.js (hala .js dosyası)
// tsconfig'de checkJs: true ile
/**
* @param {string} text
* @param {number} maxLength
* @returns {string}
*/
function truncate(text, maxLength) {
if (text.length <= maxLength) return text;
return text.slice(0, maxLength) + '...';
}
/**
* @typedef {Object} PaginationOptions
* @property {number} page
* @property {number} limit
* @property {string} [sortBy]
* @property {'asc' | 'desc'} [order]
*/
/**
* @param {PaginationOptions} options
*/
function paginate(options) {
// ...
}
Araç ve Otomasyon
# ts-migrate: Airbnb'nin otomatik migration aracı
npx ts-migrate-full src/
# typescript-strict-plugin: Dosya bazlı strict kontrol
npm install -D typescript-strict-plugin
# tsconfig.json
{
"compilerOptions": {
"plugins": [{ "name": "typescript-strict-plugin" }]
}
}
Migration Kontrol Listesi
- TypeScript ve tip tanımlarını yükle
tsconfig.jsonoluştur (allowJs: true,strict: false)- Build scriptlerini güncelle
- Paylaşılan tipleri ve interface'leri tanımla
- Utility dosyalarından başlayarak kademeli dönüştür
- Tüm
anykullanımlarını azalt - Strict ayarları kademeli olarak etkinleştir
allowJs: falseyap (tüm dosyalar dönüştürüldüğünde)strict: trueetkinleştir- CI/CD pipeline'a tip kontrolü ekle
Sonuç
JavaScript'ten TypeScript'e geçiş, kademeli ve planlı yapıldığında projeye minimum kesinti ile maksimum fayda sağlar. allowJs ile başlayın, öncelikli dosyaları dönüştürün ve strict ayarları aşamalı olarak etkinleştirin. Her adımda testlerinizi çalıştırarak regresyonları önleyin. Migration tamamlandığında tip güvenliği, daha iyi IDE desteği ve azaltılmış runtime hataları ile ödüllendirileceksiniz.