Bölüm 7: Generics - Reusable ve Type Safe Yapılar

Giriş: Generics Neden Vardır?
JavaScript’te fonksiyonlar ve bileşenler genelde her tür veriyle çalışacak şekilde yazılır. Ancak bu durum, kodun neyle çalıştığını belirsiz hale getirir ve hatalara yol açar.
TypeScript’in “generic” yapısı, bu esnekliği tip güvenliği ile birleştirerek şu avantajları sağlar:
- ✅ Kod tekrarını azaltır
- ✅ Daha esnek hale getirir
- ✅ Tipleri otomatik yakalar (inference)
- ✅ Derleme anında hata önler
- ✅ İleri düzey yapıların temelini oluşturur
Generic Kavramı Nedir?
Generic, bir tür parametresi (örneğin T
) alarak tanım yaptığımız bir yapıdır. Sanki fonksiyon gibi ama fonksiyon tipler üzerinde çalışıyor.
1function identity<T>(value: T): T {2return value;3}
T
bir type parametresi- Fonksiyon
T
tipinde değer alır veT
tipinde döner - Bu,
number
,string
,boolean
,object
… her şey olabilir
Temel Generic Fonksiyon
1function getFirst<T>(arr: T[]): T {2return arr[0];3}
Kullanımı:
1const firstNumber = getFirst([1, 2, 3]);2const firstName = getFirst(["Ali", "Veli"]);
Tipi T
çağırırken otomatik çıkarılır (type inference), ancak istersen şöyle açık da yazabilirsin:
1const item = getFirst<string>(["a", "b"]);
Generic Olmadan Ne Olurdu?
1function getFirst(arr: any[]): any {2return arr[0];3}45const name = getFirst(["Ali"]);6name.toUpperCase(); // ❌ hata olabilir
➡️ any
tipi, TypeScript’in tip kontrolünü devre dışı bırakır ve otomatik tamamlama, hata önleme, dönüş tipi denetimi gibi özellikler kaybolur.
Birden Fazla Generic Parametre Kullanmak
1function merge<T, U>(a: T, b: U): [T, U] {2return [a, b];3}45const result = merge({ name: "Yasin" }, { age: 26 });
T
: ilk parametre tipiU
: ikinci parametre tipi- Dönüş tipi:
[T, U]
yani bir tuple
Generic Kısıtlama (extends
)
Örnek: name
özelliği olan bir veri
1function getDisplayName<T extends { name: string }>(item: T): string {2return `Adı: ${item.name}`;3}45getDisplayName({ name: "Yasin", age: 25 });6getDisplayName({ age: 25 }); // ❌ Error
Varsayılan Generic Tipi Belirtme
1function toArray<T = string>(item?: T): T[] {2return [item!];3}45toArray();6toArray(123);
Generic + keyof
ile Alan Doğrulama
1function getValue<T, K extends keyof T>(obj: T, key: K): T[K] {2return obj[key];3}45const user = { name: "Yasin", age: 26 };6getValue(user, "name");7getValue(user, "age");
Generic Interface ve Type Kullanımı
1interface ApiResponse<T> {2status: number;3data: T;4}
1const userResponse: ApiResponse<{ id: number; name: string }> = {2status: 200,3data: { id: 1, name: "Yasin" },4};
React ile Generic Component Kullanımı
Amaç: Her türlü veriyi destekleyen bir <Select> bileşeni yazmak
1type SelectProps<T> = {2options: T[];3getLabel: (item: T) => string;4onChange: (selected: T) => void;5};
1function Select<T>({ options, getLabel, onChange }: SelectProps<T>) {2return (3<select onChange={(e) => onChange(options[e.target.selectedIndex])}>4{options.map((item, i) => (5<option key={i}>{getLabel(item)}</option>6))}7</select>8);9}
1type Country = { code: string; name: string };23const countries: Country[] = [4{ code: "TR", name: "Türkiye" },5{ code: "DE", name: "Almanya" },6];78<Select9options={countries}10getLabel={(item) => item.name}11onChange={(val) => console.log("Seçilen:", val)}12/>
Karma Kullanım: Partial
, Pick
, Record
+ Generics
1type ApiResult<T> = {2data: T;3error?: string;4loading: boolean;5};
1const productState: ApiResult<{ id: number; name: string }> = {2data: { id: 1, name: "Masa" },3loading: false,4};
Mini Alıştırmalar
function wrapInArray<T>(value: T): T[]
fonksiyonunu yaz.function filterByField<T, K extends keyof T>(arr: T[], field: K, value: T[K]): T[]
fonksiyonunu yaz.GenericSelect<T>
bileşeni içinvalueKey
gibi ekstra props ekle ve value değerini objeden almasını sağla.
Bölüm Özeti
Yapı | Açıklama |
---|---|
function <T>() | Generic fonksiyon tanımı |
T , U | Tip parametreleri |
T[] , T[K] | Generic dizi/alan tipi |
T extends X | Kısıtlanmış generic tip |
T = Default | Varsayılan generic |
keyof T | Tipin alan isimlerini alır |
React + Generics | Generic component + props uyumu |
Bu Bölümle Artık:
- Fonksiyonlar, type’lar ve bileşenler için yeniden kullanılabilir generic yapılar oluşturabilirsin.
- Hem tip güvenliği sağlayabilir hem de yeniden kullanılabilirlik elde edebilirsin.
- React ve API projelerinde gerçek dünyaya uygun, profesyonel yapılar kurabilirsin.