Typescript Infer Keyword Hakkında

Herkese merhaba arkadaşlar. İsmim Mert ve özel bir şirkette Full Stack Developer olarak çalışıyorum. Bugün size Typescript'de sıkça gördüğümüz infer keyword'unu açıklamaya çalışacağım.

Öncelikle Typescript nedir?

Typescript Microsoft tarafından geliştirilen ve geliştirilmeye devam eden bir Javascript supersetidir.

Peki Javascript nedir?

Javascript, web sayfalarının üzerinde çalışan elementleri interaktif hale getirmek için kullanılan bir programlama dilidir. Günümüzde en çok kullanılan programlama dillerinden birisidir. (Belki de en çoğu) Günümüzde Node.js'in popüler olmasıyla bu amacının dışında bir çok yerde kullanılıyor. Örneğin mobil uygulama geliştirme (React Native), Masaüstü(Electron js) vb. gibi. Bu konular zaten başlı başına ayrı birer konudur. Konuyu çok dağıtmadan infer keyword'unu anlamaya çalışalım.

Eğer bir programlama geçmişiniz varsa ya da hali hazırda bir yazılım geliştirme ile uğraşıyorsanız Generic Programming konusunu duymuşsunuzdur. Generic programlama genel olarak türden bağımsızdır.

infer keyword'u de tam bu noktada devreye giriyor. Infer'de zaten ingilizce'de anlam çıkarmak manasına geliyor. Generic programlamada türler genel(bağımsız) olduğu için infer ile bu türlerden anlam çıkartabiliyoruz. Bir kaç örnek ile çok daha iyi anlaşılacağına eminim.

Örneğin javascript'deki Array bir generic type'dır. Ve kendine özgü metotları vardır.

const array = [1, 2, 3];

Array<T> = {
    length: number;
    toString(): string;
    toLocaleString(): string;
    ...
}

array'e baktığımızda bu değişkenin Array<number> türünde olduğunu görebiliriz ve map, filter ve reduce gibi array türüne ait metotlarını kullanabiliriz.

Örneğin şöyle genel bir fonksiyon daha yazalım:

function tipiGetir<T>(veri: T): T {
    return veri;
}

buradaki T türü temsil eder. Örneğin söyle bir değişken yazdığımızda:

let yas = veriGetir(10);

burada yas değişkenin Typescript derleyicisi bir sayı türünde olduğunu anlayabilir. Çünkü bu basit bir şeydir. Fakat bazen derleyici bunu anlayamaz, bunu bizim anlatmamız gerekebilir.
Infer keyword anlamak için genel türleri ve koşullu türleri anlamanız gerekir.

Örneğin:

interface Insan {
    ad: string;
    yas: number;
}

Insan türünde bir arayüz oluşturduk. Şimdi de Isci adında bir arayüz oluşturup bu arayüzü Insan tipinden genişletmeye çalışalım.

interface Isci extends Insan {
    maas: number;
}

Şimdi de bu Isci arayüzü Insan sınıfını genişletiyor mu ona göre bir tür yazmaya çalışalım. Bu kısım conditional type'lara bir örnektir.

type GenisletiyorMu = Isci extends Insan ? true : false;

Burada GenisletiyorMu türünün değeri hep true olacaktır. Çünkü Isci arayüzünün her zaman Insan sınıfını genişletiyor.

Inferde conditional type'lardan bir anlam çıkarmamızı sağlar.

Örneğin bir tür tanımlayalım ve bu tür ile dizi elemanının türünü çıkaralım.

Bir örnek ile daha net olacaktır:

type GenelDiziElemani<T> = T extends Array<infer U> ? U : never;

let dizi: Array<number> = [1, 2, 3];

type DiziElemaniTipi = GenelDiziElemani<typeof dizi>;

ilk satırda bir tür belirledik ve bu türün array tipinden mi türetildiğini kontrol ettik. Infer keywordu ile eğer türetildi ise o türü, türetilmedi ise never türünü döndürüyoruz.

İkinci satırda bir sayı dizisi tanımladık.

Üçüncü satırda ise bu dizinin elemanın türünü çıkartmaya çalıştık.

Gördüğünüz gibi DiziElemaniTipi türünün değeri number türünden olacaktır.

Çünkü dizimizin içindeki elemanlar number türündedir.

Eğer dizimizin içine karışık elemanlar koysaydık:

let dizi = [1, 2, 3, "4"];

type DiziElemaniTipi = GenelDiziElemani<typeof dizi>;

Gördüğünüz gibi DiziElemaniTipi türünün değeri number | string türünden olacaktır.

Bir kaç örnek daha ekleyelim ve ne işe yaradıklarını siz çözmeye çalışın.

Bu örnekte bir fonksiyonun dönüş türünü çıkarıyoruz:

type ReturnType = T extends (...args: any[]) => infer R ? R : never;

Bu örnekte ise promise edilen türün dönüş türünü çıkarıyoruz.

type Await<T> = T extends Promise<infer U> ? U : T;

Özetle, infer keyword'unun en önemli özelliği koşullu türlerden anlam çıkarabilmemizi sağlamasıdır.

Umarım açıklayıcı olmuştur.

Yazar: Mert Genç

Kişisel Web Sitem
Github Hesabım