JavaScript'te bir fonksiyona yanlış tipte parametre geçirmek, çoğu zaman uygulamayı hemen patlatmaz. Hata, kullanıcı o belirli ekranı açtığında, üç hafta sonra, prod ortamında ortaya çıkar. TypeScript'in var olma sebebi tam olarak bu: hataları, kod çalışmadan önce, editörünüzde yakalamak. Microsoft'un geliştirdiği bu dil, JavaScript'in üzerine statik tip sistemi ekleyerek aynı işi yapar ama çok daha az sürprizle.
TypeScript bir alternatif değil, JavaScript'in üst kümesi. Yani elinizdeki her .js dosyası, uzantısını .ts yapıp derleseniz bile geçerli TypeScript'tir. Bu yazıda tip sisteminin nasıl çalıştığını, JavaScript'ten pratik farklarını ve gerçek kod örnekleriyle nasıl başlanacağını anlatıyoruz.
TypeScript Nedir, Nasıl Çalışır
TypeScript kodu doğrudan tarayıcıda çalışmaz; derleyici (tsc) onu düz JavaScript'e çevirir. Bu derleme adımı sırasında tip hataları yakalanır, derleme başarısız olursa kod üretilmez. Basit bir örnek üzerinden bakalım:
function topla(a: number, b: number): number {
return a + b;
}
topla(5, "10"); // Derleme hatası: string, number'a atanamaz
JavaScript'te bu satır sessizce çalışır ve "510" gibi beklenmedik bir sonuç üretir. TypeScript ise bunu derleme aşamasında, kod çalışmadan yakalar. Projeyi derlemek için:
npm install -g typescript
tsc dosya.ts
Çoğu modern proje tsc'yi doğrudan çağırmaz; Vite, webpack veya Next.js gibi araçlar derlemeyi arka planda kendi build sürecine gömer. JavaScript ve web standartları hakkında güvenilir bir referans için MDN Web Docs sayfasına bakabilirsiniz; TypeScript'i anlamak için sağlam bir JavaScript temeli şart.
Editör entegrasyonu, TypeScript'in gerçek gücünün ortaya çıktığı yer. VS Code, TypeScript'i kendi motoruyla çalıştırır; bu yüzden .ts dosyası açtığınızda ayrı bir eklenti kurmanıza bile gerek kalmadan tip hataları kırmızı çizgiyle işaretlenir. Bir fonksiyonun üzerine gelip parametre tiplerini görmek, yanlış kullanımı yazarken fark etmek, günlük geliştirme akışını gözle görülür şekilde hızlandırır.
Temel Tipler ve Tip Çıkarımı
TypeScript'te değişken tipini açıkça yazabilirsiniz, ama çoğu zaman gerek kalmaz. Derleyici, atanan değerden tipi otomatik çıkarır:

let isim = "Ahmet"; // string olarak çıkarılır
let yas: number = 32; // açık tip tanımı
let aktif: boolean = true;
const kullanicilar: string[] = ["ali", "veli"];
any tipi, TypeScript'in tip kontrolünü tamamen devre dışı bırakır; kullanmak çoğu zaman kod kokusudur. Bunun yerine belirsiz tipler için unknown tercih etmek daha güvenlidir çünkü unknown değeri kullanmadan önce tip kontrolü zorunlu kılar. Birden fazla tipten birini kabul eden değişkenler için union tipleri kullanılır:
function idYazdir(id: number | string): void {
console.log(`ID: ${id}`);
}
Arayüzler ve Tip Tanımları
Interface, bir nesnenin şeklini tanımlar. Bir fonksiyon belirli yapıda bir nesne bekliyorsa, bu beklentiyi interface ile açıkça yazmak, hem editör desteği hem de dokümantasyon sağlar:
interface Kullanici {
id: number;
ad: string;
email: string;
aktif?: boolean; // opsiyonel alan
}
function kullaniciGoster(k: Kullanici): string {
return `${k.ad} (${k.email})`;
}
Yanlış şekilde bir nesne geçirmeye çalıştığınızda derleyici hemen uyarır: eksik bir alan, yanlış tipte bir değer, hepsi kod çalışmadan yakalanır. Interface'ler ayrıca birbirini genişletebilir; ortak alanları taşıyan bir temel interface tanımlayıp, özel alanları alt interface'lerde eklemek, tekrarı azaltır:
interface Kisi {
ad: string;
email: string;
}
interface Calisan extends Kisi {
maas: number;
departman: string;
}
Interface'lere ek olarak type anahtar kelimesiyle tip takma adları da tanımlanabilir; ikisi çoğu senaryoda birbirinin yerine geçer, ama birleşim (union) tipleri tanımlarken type daha pratiktir.
type Durum = "beklemede" | "onaylandi" | "iptal";
let siparisDurumu: Durum = "beklemede";
Bu tarz string literal union'lar, sabit bir değer kümesini enum yazmadan tanımlamanın kısa yolu. Büyük bir kod tabanında, bir veri yapısını değiştirdiğinizde onu kullanan tüm yerler derleyici tarafından otomatik işaretlenir; bu, güvenli refactoring'in temelidir.
Jenerikler (Generics)
Jenerikler, aynı fonksiyonu farklı tiplerle yeniden kullanmanızı sağlar, tip güvenliğinden ödün vermeden. Aşağıdaki fonksiyon, hangi tipte dizi verirseniz verin ilk elemanı doğru tipte döner:

function ilkEleman<T>(dizi: T[]): T {
return dizi[0];
}
const sayi = ilkEleman([1, 2, 3]); // number
const metin = ilkEleman(["a", "b", "c"]); // string
Jenerikler olmadan bu tür bir fonksiyon ya any kullanmak zorunda kalır ya da her tip için ayrı ayrı yazılmalıdır. React ile çalışanlar, useState gibi kullanımlarda jenerikleri zaten dolaylı olarak görür. Bu özellik ilk bakışta soyut gelse de, kütüphane geliştirirken ya da paylaşılan yardımcı fonksiyonlar yazarken pratik faydası hızla ortaya çıkar.
Birden fazla tip parametresi de tanımlanabilir. Örneğin bir API çağrısını saran genel bir yardımcı fonksiyon, hem istek hem de yanıt tipini jenerik olarak alabilir:
async function apiCagir<TYanit>(url: string): Promise<TYanit> {
const yanit = await fetch(url);
return yanit.json() as TYanit;
}
interface Urun {
id: number;
ad: string;
fiyat: number;
}
const urunler = await apiCagir<Urun[]>("/api/urunler");
Bu yaklaşım, her API uç noktası için ayrı bir fonksiyon yazmak yerine tek bir genel fonksiyonu farklı veri tipleriyle yeniden kullanmanızı sağlar; yanıtın şeklini TYanit üzerinden tanımladığınız için, urunler değişkeninin Urun[] tipinde olduğunu editör otomatik bilir.
JavaScript'ten TypeScript'e Geçiş
Mevcut bir JavaScript projesini bir gecede TypeScript'e çevirmek zorunda değilsiniz. tsconfig.json dosyasında allowJs ve checkJs seçeneklerini açarak, .js dosyalarınızı olduğu gibi bırakıp yeni dosyaları .ts uzantısıyla yazabilirsiniz:

{
"compilerOptions": {
"allowJs": true,
"checkJs": false,
"strict": true,
"target": "ES2020"
}
}
strict modu açıkken derleyici çok daha titiz davranır: null ve undefined kontrolleri, örtük any kullanımı gibi noktalarda uyarı verir. Yeni bir projeye strict: true ile başlamak, ileride tip gevşekliğinden doğacak hataları baştan önler. Mevcut büyük bir kod tabanında ise strict modunu kademeli açmak, bir anda yüzlerce hatayla boğuşmaktan kurtarır.
Aşağıdaki tablo, JavaScript'ten TypeScript'e geçerken sık karşılaşılan iki yaklaşımı karşılaştırıyor:
| Yaklaşım | Ne zaman uygun | Risk |
|---|---|---|
Kademeli geçiş (allowJs) | Büyük, aktif kullanılan mevcut proje | Karma kod tabanı bir süre karmaşık kalır |
Sıfırdan strict | Yeni proje | Başlangıçta öğrenme eğrisi daha dik |
Nerede Kullanılır
TypeScript yalnızca ön yüzle sınırlı değil. Node.js üzerinde çalışan bir API sunucusunu da TypeScript ile yazabilirsiniz; bu sayede hem istemci hem sunucu tarafında aynı tip tanımlarını paylaşabilirsiniz. React, Vue ve Angular gibi çerçevelerin hepsi TypeScript'i birinci sınıf destekler; Next.js gibi framework'lerde proje oluşturma sihirbazı TypeScript'i varsayılan olarak sunar.
Kütüphane geliştirenler için TypeScript ayrı bir avantaj sağlar: bir paket TypeScript tip tanımlarıyla yayınlandığında, o paketi kullanan geliştiriciler editörde otomatik tamamlama ve tip kontrolünden doğrudan yararlanır. npm üzerindeki popüler paketlerin büyük kısmı ya doğrudan TypeScript ile yazılıyor ya da @types/ altında ayrı tip tanımları sağlıyor.
Bir paketin tip tanımı olup olmadığını hızlıca kontrol etmek için paketi kurduktan sonra node_modules/@types/ klasörüne bakabilir ya da doğrudan npm info paket-adi types komutunu çalıştırabilirsiniz. Tip tanımı olmayan eski bir kütüphane kullanıyorsanız, kendi minimal tip tanımınızı bir .d.ts dosyasında yazıp projeye dahil etmek de mümkün; bu, üçüncü parti kodla çalışırken tip güvenliğini tamamen kaybetmemenin pratik bir yolu.
Pratik Öğrenme Yolu
TypeScript öğrenmenin ön koşulu, JavaScript'in temellerine hâkim olmak; değişkenler, fonksiyonlar, nesneler ve promise'ler konusunda rahatsanız geçiş hızlı olur. Öğrenme sırası genellikle şöyle işler: önce temel tipler ve tip çıkarımı, sonra interface'ler, ardından union tipleri ve en son jenerikler.
Küçük bir komut satırı aracı ya da mevcut bir JavaScript betiğini TypeScript'e çevirmek, en etkili pratik yöntemi. Gerçek bir hatayı derleyicinin yakaladığını gördüğünüzde, tip sisteminin neden bu kadar değerli olduğu somutlaşır. tsc --noEmit komutu, dosya üretmeden yalnızca tip kontrolü yapar ve bu, öğrenirken hızlı geri bildirim almanın pratik bir yolu:
tsc --noEmit --strict dosya.ts
Zamanla, any kullanmadan yazılmış bir kod tabanının editördeki otomatik tamamlama kalitesi ile any dolu bir kod tabanı arasındaki farkı doğrudan hissedeceksiniz. Statik tipleme, yazarken biraz daha fazla düşünmeyi gerektirir ama bu düşünme, üç ay sonra kodu tekrar okuduğunuzda geri öder.
Aşağıdaki liste, TypeScript'e yeni başlayanların genellikle atladığı ama öğrenmeye değer birkaç noktayı topluyor:
strictmodunu baştan açmak, alışkanlık kazanmayı kolaylaştırıranyyerineunknownkullanıp tip daraltma (type narrowing) yapmayı öğrenmek- Interface ile type arasındaki farkı proje ihtiyacına göre seçmek
- Editörün "go to definition" ve "find references" özelliklerini aktif kullanmak
Bu alışkanlıklar, TypeScript'in sunduğu güvenliği tam olarak kullanmanızı sağlar. Aksi hâlde dili kurmuş ama any ile doldurulmuş bir kod tabanı, JavaScript'in dinamik yapısının dezavantajlarını korurken TypeScript'in derleme süresi maliyetini de üstlenmiş olur; bu durumdan kaçınmak, dili öğrenirken en çok dikkat edilmesi gereken nokta.
Kaynaklar ve doğrulama
Bilgileri uygulamadan önce güncel ayrıntıları aşağıdaki birincil veya alan otoritesi kaynaklardan kontrol edin.
Henüz yorum yok.
Sohbete katıl. Yorumlar yayınlanmadan önce moderasyondan geçer.