TypeScript'te Generikler
Bu makale, TypeScript'teki generikleri açıklar.
YouTube Video
TypeScript'te Generikler
TypeScript'teki generikler, türleri parametreleştirerek yeniden kullanılabilir ve tür güvenli işlevler, sınıflar ve arabirimler tanımlamanıza olanak tanıyan bir özelliktir. Generik kullanmak, belirli türlere bağlı olmayan kod yazmanıza olanak tanır ve böylece çeşitli türler üzerinde aynı işlemleri gerçekleştirmenizi sağlar.
Generiklerin Temelleri
Generikler, türleri argüman olarak kabul eden ve işlevlerin ve sınıfların farklı türleri işlemesine olanak tanıyan şablonlar gibi davranır.
Generik İşlevler
Aşağıdaki, argüman türleri generikler kullanılarak belirtilmiş bir işlev örneğidir.
1function identity<T>(value: T): T {
2 return value;
3}
4
5console.log(identity<number>(42)); // 42
6console.log(identity<string>("Hello")); // Hello
T
, işlevin argümanlarının ve dönüş değerinin türlerini temsil eden bir generik tür argümanıdır. Gerçek tür, işlev çağrıldığında belirlenir.<number>
veya<string>
ifadesini açıkça belirterek türü belirlemiş olursunuz.
Generik türler, TypeScript'in tür çıkarımı yaptığı için açıkça belirtilmeden de çalışır.
1function identity<T>(value: T): T {
2 return value;
3}
4
5console.log(identity(42)); // 42
6console.log(identity("Hello")); // Hello
Generikler Üzerindeki Kısıtlamalar
Generikler üzerinde kısıtlamalar koyarak, yalnızca belirli türleri kabul etmelerini sınırlayabilirsiniz.
1function loggingIdentity<T extends { length: number }>(arg: T): T {
2 console.log(arg.length);
3 return arg;
4}
5
6loggingIdentity("Hello"); // 5
7loggingIdentity([1, 2, 3]); // 3
8
9// loggingIdentity(42); // Error: number does not have a length property.
T extends { length: number }
belirterek,T
'nin birlength
özelliğine sahip bir tür olması gerektiğini belirtirsiniz. Bu nedenle,length
özelliği olmayan türler kabul edilmez.
Generik Sınıflar
Sınıflar da generikler kullanılarak tanımlanabilir. Generik sınıflar, özellikler ve yöntemler için esnek türler sunar.
1class Box<T> {
2 private _value: T;
3
4 constructor(value: T) {
5 this._value = value;
6 }
7
8 public getValue(): T {
9 return this._value;
10 }
11
12 public setValue(value: T): void {
13 this._value = value;
14 }
15}
16
17const numberBox = new Box<number>(100);
18console.log(numberBox.getValue()); // 100
19
20const stringBox = new Box<string>("Hello");
21console.log(stringBox.getValue()); // Hello
Box<T>
, sınıf içinde kullanılanT
türünü bir generik olarak tanımlar. Bu, aynı sınıfın farklı türler için yeniden kullanılmasına olanak tanır.
Generik Arabirimler
Generikler, arabirimlerle de kullanılabilir.
1interface Pair<T, U> {
2 first: T;
3 second: U;
4}
5
6const numberStringPair: Pair<number, string> = { first: 1, second: "One" };
7console.log(numberStringPair); // { first: 1, second: 'One' }
8
9const booleanArrayPair: Pair<boolean, number[]> = { first: true, second: [1, 2, 3] };
10console.log(booleanArrayPair); // { first: true, second: [ 1, 2, 3 ] }
Pair<T, U>
ile iki generik tür belirterek, farklı türlerin bir kombinasyonu ile bir nesne tanımlayabilirsiniz.
Varsayılan Tür Argümanları
Genel tür argümanları için varsayılan bir tür belirtmek de mümkündür.
1function createArray<T = string>(length: number, value: T): T[] {
2 return Array(length).fill(value);
3}
4
5console.log(createArray(3, "a")); // ['a', 'a', 'a']
6console.log(createArray(3, 100)); // [100, 100, 100]
- Varsayılan tür argümanını
<T = string>
ilestring
olarak ayarlıyoruz. Herhangi bir tür açıkça belirtilmezse,T
türüstring
olacaktır.
Genel Tür Takma İsimleri
Geneller, tür takma isimleri (type
) olarak da kullanılabilir.
1type Result<T> = {
2 success: boolean;
3 data: T;
4};
5
6const successResult: Result<number> = { success: true, data: 42 };
7const errorResult: Result<string> = { success: false, data: "Error occurred" };
8
9console.log(successResult); // { success: true, data: 42 }
10console.log(errorResult); // { success: false, data: 'Error occurred' }
Result<T>
türüT
olan verileri içeren bir sonuç nesnesini temsil eder. Bu şekilde, geneller kullanarak esnek tür takma isimleri oluşturabilirsiniz.
Birden Fazla Genel Tür
Birden fazla genel tür kullanarak, daha çok yönlü fonksiyonlar ve sınıflar tanımlayabilirsiniz.
1function merge<T, U>(obj1: T, obj2: U): T & U {
2 return { ...obj1, ...obj2 };
3}
4
5const person = { name: "Alice" };
6const job = { title: "Engineer" };
7
8const merged = merge(person, job);
9console.log(merged); // { name: 'Alice', title: 'Engineer' }
merge
fonksiyonuT
veU
olarak iki farklı tür alır ve bunları birleştirerek yeni bir nesne döner.
Özet
- Geneller türleri parametre olarak ele alarak yeniden kullanılabilir ve tür güvenli kod yazmayı sağlar.
- Fonksiyonlar, sınıflar ve arayüzler içinde geneller kullanarak, çeşitli türleri işleyen esnek mantık yazabilirsiniz.
- Tür argümanlarına kısıtlamalar ekleyerek veya varsayılan tür argümanlarını ayarlayarak, genellerin kapsamını kontrol edebilirsiniz.
Genelleri kullanarak tür bağımsız, genel amaçlı kod yazabilir ve TypeScript'in güçlü tür sisteminden en iyi şekilde faydalanabilirsiniz.
Yukarıdaki makaleyi, YouTube kanalımızda Visual Studio Code'u kullanarak takip edebilirsiniz. Lütfen YouTube kanalını da kontrol edin.