TypeScript Gelişmiş Jenerikler Örneklerle Açıklandı

TypeScript'teki jenerikler, çeşitli veri türleriyle çalışarak yeniden kullanılabilir ve esnek kod bileşenleri oluşturmanın bir yolunu sunar. Gelişmiş jenerikler, geliştiricilerin daha sağlam ve tür açısından güvenli kod yazmalarına olanak tanıyan kısıtlamalar, varsayılan değerler ve çoklu türler gibi ek özellikler sunarak bu kavramı daha da ileri götürür. Bu makalede, jeneriklerdeki bu gelişmiş kavramları keşfetmek için örnekler kullanılacaktır.

Genel Kısıtlamalar

Kısıtlamalar, genel bir türün kabul edebileceği türleri sınırlar. Bu, genel bir işleve veya sınıfa geçirilen türün belirli ölçütleri karşılamasını sağlar. Örneğin, genel türün belirli bir özelliğe veya yönteme sahip olduğundan emin olmak için bir kısıtlama kullanılabilir.

function getLength<T extends { length: number }>(arg: T): number {
    return arg.length;
}

const stringLength = getLength("TypeScript");
const arrayLength = getLength([1, 2, 3]);

Bu örnekte, <T extends { length: number }> kısıtlaması, getLength işlevine geçirilen argümanın length özelliğine sahip olmasını sağlar.

Çoklu Jenerikler

TypeScript, aynı işlev, sınıf veya arayüzde birden fazla genel türün kullanılmasına izin verir. Bu, birden fazla türü içeren değer çiftleri veya diğer veri yapılarıyla çalışırken yararlıdır.

function pair<T, U>(first: T, second: U): [T, U] {
    return [first, second];
}

const stringNumberPair = pair("TypeScript", 2024);

Bu fonksiyon, pair, iki farklı genel türü, T ve U, kabul eder ve her iki türü de içeren bir tuple döndürür.

Varsayılan Genel Türler

TypeScript'teki jenerikler de varsayılan tiplere sahip olabilir. Bu, belirli bir tip sağlanmadığında jeneriklerin bir yedek tipe sahip olmasını istediğinizde faydalıdır.

function identity<T = string>(value: T): T {
    return value;
}

const defaultString = identity("Hello");  // T is string
const customNumber = identity<number>(100);  // T is number

Bu örnekte, identity türüne hiçbir tür geçirilmezse, varsayılan olarak string kullanılır.

Arayüzlerle Jenerikleri Kullanma

Türlerin sabit olmadığı karmaşık yapıları tanımlamak için arayüzlerle birlikte jenerikler kullanılabilir. Bu, verilerin nasıl yönetileceğine esneklik katar.

interface Container<T> {
    value: T;
}

const stringContainer: Container<string> = { value: "Hello" };
const numberContainer: Container<number> = { value: 42 };

Container arayüzü herhangi bir türdeki değeri tutacak şekilde tasarlanmıştır ve bu sayede belirli türlere sahip farklı türde konteynerlere izin verir.

Genel Sınıflar

TypeScript'teki sınıflar da genel olabilir. Bu, özellikle veri depolama veya koleksiyon sınıfları gibi çeşitli veri türleriyle çalışan sınıflar tasarlarken faydalıdır.

class DataStore<T> {
    private data: T[] = [];

    add(item: T): void {
        this.data.push(item);
    }

    getAll(): T[] {
        return this.data;
    }
}

const stringStore = new DataStore<string>();
stringStore.add("Hello");
stringStore.add("TypeScript");

const numberStore = new DataStore<number>();
numberStore.add(42);

Bu örnekte, DataStore sınıfı her tür veriyle çalışır ve öğeleri depolamak ve almak için tür açısından güvenli bir yol sağlar.

Çözüm

TypeScript'teki gelişmiş jenerikler, esnek, yeniden kullanılabilir ve tür güvenli kod yazmak için güçlü bir araçtır. Sınıflarda ve arayüzlerde kısıtlamalar, çoklu türler, varsayılan değerler ve jenerikler kullanarak geliştiriciler daha karmaşık ve sağlam kodlar yazabilirler. Bu gelişmiş kavramları anlamak ve kullanmak daha fazla esneklik sağlar ve uygulamalar arasında tür güvenliğini garanti eder.