TypeScript Tip Sistemi: Temel Tipler ve Tip Güvenliği

TypeScript Tip Sistemi: Temel Tipler ve Tip Güvenliği
TypeScript'in en büyük gücü, güçlü ve esnek tip sistemidir. Statik tip kontrolü sayesinde hatalar daha kod yazılırken yakalanır, geliştirici deneyimi iyileşir ve kodun okunabilirliği artar. Bu yazıda TypeScript'in temel tip sistemini, primitif tiplerden karmaşık yapılara kadar kapsamlı bir şekilde inceleyeceğiz.
Primitif Tipler
TypeScript, JavaScript'teki primitif tipleri doğrudan destekler ve bunların üzerine tip güvenliği ekler:
// String
let kullaniciAdi: string = "Tarik Tunç";
let mesaj: string = `Merhaba, ${kullaniciAdi}`;
// Number (integer ve float ayrımı yoktur)
let yas: number = 28;
let pi: number = 3.14159;
let hex: number = 0xff;
let binary: number = 0b1010;
// Boolean
let aktif: boolean = true;
let dogrulanmis: boolean = false;
// BigInt (ES2020+)
let buyukSayi: bigint = 9007199254740991n;
// Symbol
let benzersiz: symbol = Symbol("açıklama");
// Null ve Undefined
let bos: null = null;
let tanimsiz: undefined = undefined;
Özel TypeScript Tipleri
TypeScript, JavaScript'te bulunmayan bazı özel tipler sunar:
any Tipi
any tipi, tip kontrolünü tamamen devre dışı bırakır. Mümkün olduğunca kaçınılmalıdır:
let hersey: any = "merhaba";
hersey = 42; // Hata yok
hersey = true; // Hata yok
hersey.method(); // Hata yok ama çalışma zamanında patlayabilir!
// unknown - any'nin güvenli alternatifi
let bilinmeyen: unknown = "merhaba";
// bilinmeyen.toUpperCase(); // HATA! unknown tipinde method çağrılamaz
// Önce tip kontrolü yapmanız gerekir
if (typeof bilinmeyen === "string") {
console.log(bilinmeyen.toUpperCase()); // Güvenli!
}
any tipini kullanmak TypeScript'in tip güvenliğini tamamen ortadan kaldırır. Bunun yerine unknown kullanın ve tip daraltma (type narrowing) ile güvenli erişim sağlayın. any yalnızca geçiş döneminde veya gerçekten kaçınılmaz durumlarda tercih edilmelidir.
void, never ve object
// void - dönüş değeri olmayan fonksiyonlar
function logla(mesaj: string): void {
console.log(mesaj);
// return ifadesi yok veya return; kullanılabilir
}
// never - asla tamamlanmayan fonksiyonlar
function hataFirlat(mesaj: string): never {
throw new Error(mesaj);
}
function sonsuzDongu(): never {
while (true) {
// Asla çıkılmaz
}
}
// object - primitif olmayan tipler
function anahtarlariGetir(obj: object): string[] {
return Object.keys(obj);
}
Array ve Tuple Tipleri
TypeScript'te diziler ve tuple'lar farklı şekillerde tanımlanabilir:
// Array tanımlama yöntemleri
let sayilar: number[] = [1, 2, 3, 4, 5];
let isimler: Array<string> = ["Ali", "Ayşe", "Mehmet"];
// Readonly array
let sabitListe: readonly number[] = [1, 2, 3];
// sabitListe.push(4); // HATA! readonly diziye eleman eklenemez
// Tuple - sabit uzunlukta ve tipte dizi
let koordinat: [number, number] = [41.0082, 28.9784];
let kullanici: [string, number, boolean] = ["Tarik", 28, true];
// Named tuple (TypeScript 4.0+)
type Nokta = [x: number, y: number, z?: number];
let nokta2D: Nokta = [10, 20];
let nokta3D: Nokta = [10, 20, 30];
// Rest elements in tuples
type StringVeSayilar = [string, ...number[]];
let veri: StringVeSayilar = ["toplam", 1, 2, 3, 4];
Literal Tipler
Literal tipler, değişkenlerin alabildiği değerleri tam olarak sınırlar:
// String literal types
type Yon = "kuzey" | "guney" | "dogu" | "bati";
let yonelim: Yon = "kuzey"; // Geçerli
// let yonelim: Yon = "yukari"; // HATA!
// Numeric literal types
type Zar = 1 | 2 | 3 | 4 | 5 | 6;
let sonuc: Zar = 3; // Geçerli
// Boolean literal types
type Dogru = true;
let evet: Dogru = true;
// const assertion ile literal tip çıkarımı
const config = {
url: "https://api.example.com",
timeout: 5000,
retries: 3
} as const;
// config.url tipi "https://api.example.com" olur, string değil
as const assertion'ı, bir nesnenin tüm özelliklerini readonly ve literal tip olarak işaretler. Bu, özellikle Redux action'ları ve konfigürasyon objeleri gibi değişmemesi gereken değerler için çok faydalıdır.
Tip Çıkarımı (Type Inference)
TypeScript, birçok durumda tipleri otomatik olarak çıkarabilir. Her yere tip yazmak zorunda değilsiniz:
// TypeScript tipi otomatik çıkarır
let mesaj = "Merhaba"; // string
let sayi = 42; // number
let liste = [1, 2, 3]; // number[]
let karisik = [1, "iki"]; // (string | number)[]
// Fonksiyon dönüş tipi çıkarımı
function topla(a: number, b: number) {
return a + b; // Dönüş tipi number olarak çıkarılır
}
// Contextual typing
const isimler = ["Ali", "Ayşe", "Mehmet"];
isimler.forEach((isim) => {
// isim otomatik olarak string tipinde
console.log(isim.toUpperCase());
});
// Destructuring ile tip çıkarımı
const { id, name } = { id: 1, name: "Tarik" };
// id: number, name: string
Tip Uyumluluğu (Type Compatibility)
TypeScript, yapısal tip sistemi (structural type system) kullanır. Bu, tiplerin adına değil yapısına bakıldığı anlamına gelir:
interface Kedi {
isim: string;
miyavla(): void;
}
interface Hayvan {
isim: string;
}
let kedi: Kedi = { isim: "Tekir", miyavla: () => console.log("Miyav!") };
let hayvan: Hayvan = kedi; // Geçerli! Kedi, Hayvan'ın tüm özelliklerine sahip
// Tersine atanamaz:
// let kedi2: Kedi = hayvan; // HATA! Hayvan'da miyavla() yok
Type Assertion ve Type Casting
Bazen TypeScript'e bir değerin tipini siz daha iyi bilirsiniz:
// as sözdizimi (önerilen)
const input = document.getElementById("email") as HTMLInputElement;
input.value = "tarik@example.com";
// Çift assertion (dikkatli kullanın)
const deger = "merhaba" as unknown as number; // Tehlikeli!
// Non-null assertion operatörü
function kullaniciAdiGetir(id: number): string | undefined {
// ...
return undefined;
}
const ad = kullaniciAdiGetir(1)!; // undefined olmadığını garanti ediyorsunuz
// Eğer undefined ise çalışma zamanında hata alırsınız!
Sonuç
TypeScript'in tip sistemi, JavaScript'e güçlü bir güvenlik katmanı ekler. Primitif tiplerden başlayarak literal tipler, tuple'lar ve özel tipler (any, unknown, never, void) gibi kavramları öğrenmek, TypeScript'te ustalaşmanın ilk adımıdır. Tip çıkarımı sayesinde her yere tip yazmanıza gerek kalmaz, ancak karmaşık yapılarda açık tip tanımları kodunuzu daha okunabilir ve güvenli hale getirir.
Bir sonraki adım olarak interface ve type arasındaki farkları inceleyerek tip sisteminizi daha da güçlendirebilirsiniz.