GitHub

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

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.

1
function identity<T>(value: T): T {
2
return value;
3
}
  • T bir type parametresi
  • Fonksiyon T tipinde değer alır ve T tipinde döner
  • Bu, number, string, boolean, object… her şey olabilir

Temel Generic Fonksiyon

1
function getFirst<T>(arr: T[]): T {
2
return arr[0];
3
}

Kullanımı:

1
const firstNumber = getFirst([1, 2, 3]);
2
const firstName = getFirst(["Ali", "Veli"]);

Tipi T çağırırken otomatik çıkarılır (type inference), ancak istersen şöyle açık da yazabilirsin:

1
const item = getFirst<string>(["a", "b"]);

Generic Olmadan Ne Olurdu?

1
function getFirst(arr: any[]): any {
2
return arr[0];
3
}
4
5
const name = getFirst(["Ali"]);
6
name.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

1
function merge<T, U>(a: T, b: U): [T, U] {
2
return [a, b];
3
}
4
5
const result = merge({ name: "Yasin" }, { age: 26 });
  • T: ilk parametre tipi
  • U: ikinci parametre tipi
  • Dönüş tipi: [T, U] yani bir tuple

Generic Kısıtlama (extends)

Örnek: name özelliği olan bir veri

1
function getDisplayName<T extends { name: string }>(item: T): string {
2
return `Adı: ${item.name}`;
3
}
4
5
getDisplayName({ name: "Yasin", age: 25 });
6
getDisplayName({ age: 25 }); // ❌ Error

Varsayılan Generic Tipi Belirtme

1
function toArray<T = string>(item?: T): T[] {
2
return [item!];
3
}
4
5
toArray();
6
toArray(123);

Generic + keyof ile Alan Doğrulama

1
function getValue<T, K extends keyof T>(obj: T, key: K): T[K] {
2
return obj[key];
3
}
4
5
const user = { name: "Yasin", age: 26 };
6
getValue(user, "name");
7
getValue(user, "age");

Generic Interface ve Type Kullanımı

1
interface ApiResponse<T> {
2
status: number;
3
data: T;
4
}
1
const userResponse: ApiResponse<{ id: number; name: string }> = {
2
status: 200,
3
data: { id: 1, name: "Yasin" },
4
};

React ile Generic Component Kullanımı

Amaç: Her türlü veriyi destekleyen bir <Select> bileşeni yazmak

1
type SelectProps<T> = {
2
options: T[];
3
getLabel: (item: T) => string;
4
onChange: (selected: T) => void;
5
};
1
function Select<T>({ options, getLabel, onChange }: SelectProps<T>) {
2
return (
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
}
1
type Country = { code: string; name: string };
2
3
const countries: Country[] = [
4
{ code: "TR", name: "Türkiye" },
5
{ code: "DE", name: "Almanya" },
6
];
7
8
<Select
9
options={countries}
10
getLabel={(item) => item.name}
11
onChange={(val) => console.log("Seçilen:", val)}
12
/>

Karma Kullanım: Partial, Pick, Record + Generics

1
type ApiResult<T> = {
2
data: T;
3
error?: string;
4
loading: boolean;
5
};
1
const productState: ApiResult<{ id: number; name: string }> = {
2
data: { id: 1, name: "Masa" },
3
loading: 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çin valueKey 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, UTip parametreleri
T[], T[K]Generic dizi/alan tipi
T extends XKısıtlanmış generic tip
T = DefaultVarsayılan generic
keyof TTipin alan isimlerini alır
React + GenericsGeneric 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.