İçeriğe geç
academia.sh

Ders 17 / 23

Yardımcı Tipler

Standart kitaplığın hazır tip dönüşümleri; alan değiştiricileri, alan seçme ve dışlama, tablo kurma, birleşim süzme ve imzalardan tip çıkarma araçları.

İçindekiler

Bu konuda elle yazılan dönüşümlerin çoğu — salt okunur sürüm, seçmeli sürüm, birleşimden üye eleme — standart kitaplıkta hazır bulunur. Bunlara yardımcı tip (utility type) denir.

Hepsi önceki derslerde kurulan mekanizmalarla yazılmıştır: eşlenmiş tipler, koşullu tipler, keyof ve infer. Bu derste her birinin ne yaptığı, nasıl kurulduğu ve ölçüm modelinin türevlerini yazmakta nasıl kullanıldığı ele alınır.

Alan Değiştiricileri ve Alan Seçimi

En sık kullanılan dört dönüşüm, ölçüm modelinin dört türevini tek satırda üretir:

interface Olcum {
  kimlik: string;
  sensor: string;
  deger: number;
  birim: "C" | "Pa" | "%";
  zaman: number;
}

type OlcumOzeti = Pick<Olcum, "kimlik" | "deger" | "birim">;
type OlcumGirdisi = Omit<Olcum, "kimlik" | "zaman">;
type OlcumYamasi = Partial<Omit<Olcum, "kimlik">>;
type ArsivKaydi = Readonly<Olcum>;

const ozet: OlcumOzeti = { kimlik: "s-01", deger: 21.4, birim: "C" };
const girdi: OlcumGirdisi = { sensor: "sicaklik", deger: 21.4, birim: "C" };
const yama: OlcumYamasi = { deger: 22.1 };
const arsiv: ArsivKaydi = {
  kimlik: "s-01",
  sensor: "sicaklik",
  deger: 21.4,
  birim: "C",
  zaman: 1706000000000,
};

console.log(ozet.kimlik, girdi.sensor, yama.deger, arsiv.zaman);

Çıktı s-01 sicaklik 22.1 1706000000000dir.

Dört tipin anlamı şudur. OlcumOzeti, listeleme ekranının ihtiyaç duyduğu üç alanı taşır. OlcumGirdisi, yeni kayıt oluştururken verilen alanlardır — kimlik ve zaman damgası sistem tarafından üretilir. OlcumYamasi, kısmi güncelleme isteğidir; kimlik hariç her alan verilebilir ve hiçbiri zorunlu değildir. ArsivKaydi ise değiştirilemeyen bir kayıttır.

Dördü de asıl tipten hesaplandığı için Olcum tipine yeni bir alan eklendiğinde uygun türevler kendiliğinden büyür. Elle yazılsalardı bu bağ kopardı.

Kısıtların gerçekten uygulandığı iki tanıyla görülür:

interface Olcum {
  kimlik: string;
  deger: number;
  zaman: number;
}

type OlcumGirdisi = Omit<Olcum, "kimlik">;
type ArsivKaydi = Readonly<Olcum>;

const girdi: OlcumGirdisi = { kimlik: "s-01", deger: 21.4, zaman: 1 };

declare const arsiv: ArsivKaydi;
arsiv.deger = 22.1;
r2.ts(10,31): error TS2353: Object literal may only specify known properties, and 'kimlik' does not exist in type 'OlcumGirdisi'.
r2.ts(13,7): error TS2540: Cannot assign to 'deger' because it is a read-only property.

Bu dört tipin tanımları, eşlenmiş tipler dersinde elle yazılanların aynısıdır:

Yardımcı tip Karşılığı
Partial<T> { [A in keyof T]?: T[A] }
Required<T> { [A in keyof T]-?: T[A] }
Readonly<T> { readonly [A in keyof T]: T[A] }
Pick<T, A> { [B in A]: T[B] }
Record<A, D> { [B in A]: D }

Omit bu listede yoktur, çünkü doğrudan eşlemeyle değil bir bileşimle kurulur: Pick<T, Exclude<keyof T, A>>. Önce dışlanacak adlar keyof T birleşiminden çıkarılır, kalan adlar seçilir.

Omit ile Pick Arasındaki Denetim Farkı

Bu bileşimin gözden kaçan bir sonucu vardır:

interface Olcum {
  kimlik: string;
  deger: number;
}

type A = Omit<Olcum, "olmayanAlan">;
type B = Pick<Olcum, "olmayanAlan">;
r3.ts(7,22): error TS2344: Type '"olmayanAlan"' does not satisfy the constraint 'keyof Olcum'.

Tanı yalnızca Pick için gelir. Omit tipinin ikinci parametresinin kısıtı keyof T değil, herhangi bir özellik anahtarıdır; var olmayan bir alan adı sessizce yok sayılır ve sonuç Olcum ile aynı olur.

Bunun bakım açısından bedeli şudur: Olcum tipindeki bir alan yeniden adlandırıldığında, onu dışlayan Omit yazımları sessizce etkisiz hâle gelir ve dışlanması gereken alan geri gelir. Pick yazımlarında ise derleyici tanı verir.

Pratik sonuç: alan kümesi küçükse Pick yeğlenir. Omit gerekiyorsa, kısıtı sıkılaştıran bir sarmalayıcı yazılabilir:

interface Olcum {
  kimlik: string;
  deger: number;
}

type Disla<T, A extends keyof T> = Omit<T, A>;

type Guvenli = Disla<Olcum, "kimlik">;
const g: Guvenli = { deger: 21.4 };
console.log(g.deger);

Çıktı 21.4tür. Dosyanın sonuna, bir boş satırdan sonra type Yanlis = Disla<Olcum, "olmayanAlan">; satırı eklenirse:

r7.ts(12,28): error TS2344: Type '"olmayanAlan"' does not satisfy the constraint 'keyof Olcum'.

Tek fark, tip parametresine extends keyof T kısıtının konmasıdır; gövde yine Omit kullanır.

Birleşim Süzgeçleri

Üç yardımcı tip, koşullu tiplerin dağılım davranışı üzerine kurulur:

type Birim = "C" | "Pa" | "%";
type Aralik = [alt: number, ust: number];

type Araliklar = Record<Birim, Aralik>;
type SayisalBirim = Exclude<Birim, "%">;
type YuzdeBirim = Extract<Birim, "%" | "ppm">;
type TanimliDeger = NonNullable<number | null | undefined>;

const araliklar: Araliklar = {
  C: [-40, 85],
  Pa: [0, 200000],
  "%": [0, 100],
};
const sayisal: SayisalBirim = "Pa";
const yuzde: YuzdeBirim = "%";
const deger: TanimliDeger = 21.4;

console.log(araliklar.C[1], sayisal, yuzde, deger);

Çıktı 85 Pa % 21.4tür.

Tanımları koşullu tiplerle tek satırdır:

  • Exclude<T, U>T extends U ? never : T
  • Extract<T, U>T extends U ? T : never
  • NonNullable<T>T & {}

Extract örneğinde "ppm" değeri Birim birleşiminde bulunmaz ve sonuca girmez; kesişim alınıyor gibi düşünülebilir. NonNullable ise boş nesne tipiyle kesişim alarak null ve undefined üyelerini eler.

İmzalardan Tip Çıkarma

Son grup, infer üzerine kurulur ve var olan bir fonksiyonun imzasından tip türetir:

interface Olcum {
  kimlik: string;
  deger: number;
}

function olcumOlustur(kimlik: string, deger: number) {
  return { kimlik, deger, olusturmaZamani: 0 };
}

async function olcumGetir(kimlik: string): Promise<Olcum> {
  return { kimlik, deger: 21.4 };
}

type OlusanKayit = ReturnType<typeof olcumOlustur>;
type OlusturmaArgumanlari = Parameters<typeof olcumOlustur>;
type GetirilenKayit = Awaited<ReturnType<typeof olcumGetir>>;

const kayit: OlusanKayit = { kimlik: "s-01", deger: 21.4, olusturmaZamani: 0 };
const argumanlar: OlusturmaArgumanlari = ["s-02", 22.1];
const getirilen: GetirilenKayit = { kimlik: "s-03", deger: 23.0 };

console.log(kayit.olusturmaZamani, olcumOlustur(...argumanlar).kimlik, getirilen.deger);

Çıktı 0 s-02 23tür. Dosyanın sonuna, bir boş satırdan sonra const yanlis: OlusturmaArgumanlari = ["s-04"]; satırı eklenirse:

r5.ts(24,7): error TS2322: Type '[string]' is not assignable to type '[kimlik: string, deger: number]'.
  Source has 1 element(s) but target requires 2.

Tanı, Parameters sonucunun adlandırılmış bir demet olduğunu gösteriyor. ReturnType olcumOlustur fonksiyonunun çıkarılmış dönüş tipini verir; Awaited, Eşzamansız JavaScript kursunda tanıtılan sözün çözüldüğünde ürettiği değerin tipini alır ve iç içe sözleri de açar.

Bu grubun tipik kullanım yeri, bir fonksiyonun dönüş tipini elle yazmadan başka bir yerde kullanmaktır. Bir uyarı gerekir: bu bağ tek yönlüdür ve fonksiyonun gövdesi değiştiğinde türetilmiş tip de sessizce değişir. Tip Çıkarımı dersinde kurulan kural burada geçerlidir — dışa açılan bir sınırın tipi, çıkarıma bırakılmak yerine yazılmalıdır.

Yardımcı Tip Seçimi

İhtiyaç Yardımcı tip
Tüm alanları seçmeli yap Partial<T>
Tüm alanları zorunlu yap Required<T>
Tüm alanları salt okunur yap Readonly<T>
Belirli alanları tut Pick<T, A>
Belirli alanları çıkar Omit<T, A>
Anahtar kümesinden tablo kur Record<A, D>
Birleşimden üye çıkar Exclude<T, U>
Birleşimden üye seç Extract<T, U>
Boş değerleri ele NonNullable<T>
İmzadan tip türet ReturnType, Parameters, Awaited

Tablodaki her satır bu konuda kurulan bir mekanizmaya dayanır. Yardımcı tipleri ezberlemek gerekmez; ne yaptıkları, nasıl kuruldukları bilindiğinde kendiliğinden hatırlanır ve listede olmayan bir dönüşüm gerektiğinde yenisi yazılabilir.

Özet

  • Yardımcı tipler, önceki derslerde kurulan eşlenmiş ve koşullu tip mekanizmalarının standart kitaplıktaki hazır biçimleridir.
  • Pick, Omit, Partial ve Readonly bir veri modelinin türevlerini asıl tipten hesaplar; model büyüdüğünde türevler birlikte büyür.
  • Omit ikinci parametresini keyof T ile kısıtlamaz; var olmayan bir alan adı sessizce yok sayılır, Pick ise TS2344 tanısı verir.
  • Exclude, Extract ve NonNullable, koşullu tiplerin dağılım davranışı üzerine kurulmuş birleşim süzgeçleridir.
  • ReturnType, Parameters ve Awaited, infer kullanarak var olan imzalardan tip türetir; türetilen tip gövde değiştiğinde sessizce değişir.

Sonraki Adım

Ölçüm kayıtları her zaman düz bir yapı taşımaz: bir kaydın altında alt kayıtlar, bir yapılandırma nesnesinin altında iç içe bölümler bulunabilir. Böyle yapıların derinliğine uygulanan dönüşümler — her düzeyde salt okunur yapma, iç içe anahtar yollarını sayma — tipin kendisine başvurmasını gerektirir. Sonraki ders özyinelemeli tipleri ve derleyicinin onlara koyduğu sınırları ele alacak.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat