Ders 03 / 23
any, unknown ve never
Denetimi kapatan any, denetimi zorunlu kılan unknown ve hiçbir değeri olmayan never tipinin atanabilirlik kuralları ve kullanım yerleri.
İçindekiler
Önceki ders ölçüm kaydının ilk tipli sürümünü yazdı, ancak kayıt hâlâ elde yazılmış bir
nesneydi. Gerçek veri dosyadan veya ağdan gelir ve JSON.parse çağrısından çıkar. O
çağrının dönüş değeri hangi tiptedir?
Yanıt, tip sisteminin iki uç noktasını tanıtır. any tipi “her şey olabilir, denetleme”
der; unknown tipi “her şey olabilir, o yüzden önce sına” der. İkisinin arasındaki fark,
kaydın güvenliğiyle ilgili en önemli kararlardan biridir. Dersin sonunda üçüncü bir uç
gelecek: hiçbir değeri olmayan never tipi.
any: Denetimin Kapatılması
any, tip denetleyicisine bir değer hakkında hiçbir şey iddia etmemesini söyler:
const ham: any = JSON.parse('{"kimlik":"s-01","deger":"23.0"}'); console.log(ham.deger.toFixed(1)); console.log(ham.olmayan.alan); const sayi: number = ham;
Bu dosya tip denetiminden hatasız geçer. Üç satırın üçü de hatalıdır: deger alanı
dizgidir, olmayan diye bir alan yoktur ve ham bir sayı değildir. Derleyici hiçbirini
bildirmez, çünkü any değerinin hangi alanlara sahip olduğu hakkında bir iddiası yoktur.
anyin iki yönlü davranışı vardır: any tipindeki bir değer her tipe atanabilir, her tip
de anye atanabilir. Bu, tipin denetim ağından çıkarılması demektir. Bir alan any
olduğunda, o alandan türeyen her ifade de denetimsiz kalır — denetimsizlik yayılır.
JSON.parse fonksiyonunun bildirilmiş dönüş tipi anydir. Bunun nedeni açık: dizginin
içeriği ancak çalışma zamanında bilinir, derleyicinin söyleyecek bir şeyi yoktur. Sonuç,
ilk derste görülen duruma benzer — tip denetimi susar, hata çalışma zamanına ertelenir.
Derleyici, tip yazılmadığında any çıkarmayı da reddedebilir:
function ortalama(olcumler) { return olcumler.length; } console.log(ortalama([1, 2, 3]));
c6.ts(1,19): error TS7006: Parameter 'olcumler' implicitly has an 'any' type.
Bu tanı noImplicitAny seçeneğinden gelir ve katı yapılandırmanın parçasıdır. Ayrımı
görmek gerekir: örtük any bir eksikliktir, derleyici uyarır. Açık any bir
karardır, derleyici susar. Kod tabanında any yazımlarını aramak, denetimin kapatıldığı
yerleri aramak demektir.
unknown: Denetimin Ertelenmesi
unknown, any ile aynı değer kümesini kapsar — her değer unknown tipine atanabilir —
ama ters yön kapalıdır:
const ham: unknown = JSON.parse('{"kimlik":"s-01","deger":"23.0"}'); console.log(ham.deger); const sayi: number = ham;
c2.ts(3,13): error TS18046: 'ham' is of type 'unknown'. c2.ts(4,7): error TS2322: Type 'unknown' is not assignable to type 'number'.
unknown tipindeki bir değerle hiçbir şey yapılamaz: alanına erişilemez,
çağrılamaz, başka bir tipe atanamaz. Yapılabilecek tek şey, tipini daraltmaktır.
İki tipin ilişkisi bir sıralamayla anlatılabilir. Atanabilirlik yönünde unknown en üstte
durur: her tip ona atanır, o hiçbir tipe atanmaz. Bu nedenle en üst tip (top type)
denir. any ise bu sıralamanın dışındadır; her iki yöne de atanır ve tam bu yüzden bir
güvence taşımaz.
Pratik kural: sistem sınırında unknown kullanılır. Dış veri unknown olarak alınır,
sınanır, ancak sınamadan sonra modele girer.
Sınırda Doğrulama
Ölçüm kaydının dosyadan okunması bu kuralın uygulanmasıdır:
type Olcum = { kimlik: string; deger: number }; function oku(ham: string): Olcum | null { const cozulen: unknown = JSON.parse(ham); if ( typeof cozulen === "object" && cozulen !== null && "kimlik" in cozulen && typeof cozulen.kimlik === "string" && "deger" in cozulen && typeof cozulen.deger === "number" ) { return { kimlik: cozulen.kimlik, deger: cozulen.deger }; } return null; } console.log(oku('{"kimlik":"s-01","deger":21.4}')); console.log(oku('{"kimlik":"s-01","deger":"23.0"}')); console.log(oku('42'));
Çıktı:
{ kimlik: 's-01', deger: 21.4 }
null
null
Koşulun her parçası bir adım daraltma yapar. typeof cozulen === "object" ifadesinden
sonra derleyici değerin bir nesne olduğunu bilir; cozulen !== null ile null olasılığı
elenir; "kimlik" in cozulen ile o alanın varlığı kanıtlanır; typeof sınamasıyla alanın
tipi belirlenir. Koşulun içine girildiğinde derleyici cozulen.kimlik ifadesinin string
olduğunu kanıtlamıştır — programcının sözüne değil, koddaki sınamalara dayanarak.
Bu, kursun eksenidir: tip sistemi bir kanıt katmanıdır ve sınamalar kanıtın adımlarıdır. Daraltmanın kuralları ile daha az tekrar eden yazım biçimleri Tip Daraltma dersinde ele alınacaktır.
Aynı işi as Olcum yazarak yapmak da mümkündü ve ilk derste görüldüğü gibi hatalı
davranırdı. Fark şurada: as yazımında güvence programcının iddiasından, yukarıdaki
kodda ise gerçekten çalışan sınamalardan gelir.
never: Boş Tip
never, hiçbir değeri olmayan tiptir. Boş kümedir. İki yerde ortaya çıkar.
Birincisi, hiçbir zaman normal yoldan dönmeyen fonksiyonların dönüş tipi:
function dur(ileti: string): never { throw new Error(ileti); } const her: string = dur("kayit okunamadi"); const hicbir: never = "s-01"; console.log(her, hicbir);
c5.ts(6,7): error TS2322: Type '"s-01"' is not assignable to type 'never'.
Beşinci satır hata vermez, altıncı verir. Bunun nedeni neverin atanabilirlik
sıralamasındaki yeridir: never her tipe atanabilir, hiçbir tip nevere atanamaz. Boş
kümenin her kümenin alt kümesi olması gibi. Bu yüzden never en alt tip (bottom type)
diye anılır. dur fonksiyonu hiçbir değer döndürmediği için, döndürdüğü değerin string
olması gerektiğini söylemek boş bir iddiadır ve derleyici buna izin verir.
İkinci ortaya çıkışı daha yararlıdır: tükenmişlik denetimi (exhaustiveness checking). Ölçüm kaydının durumları bir birleşimle tanımlansın:
type Durum = "gecerli" | "suphe" | "hatali"; function etiket(durum: Durum): string { switch (durum) { case "gecerli": return "olcum gecerli"; case "suphe": return "olcum supheli"; default: { const elealinmayan: never = durum; return elealinmayan; } } } console.log(etiket("gecerli"));
c4.ts(10,13): error TS2322: Type '"hatali"' is not assignable to type 'never'.
Tanı, ele alınmayan durumun adını doğrudan söyler. Mekanizma şudur: iki case dalından
sonra derleyici, default dalına yalnızca "hatali" değerinin ulaşabileceğini bilir.
never tipine atama denemesi, kalan kümenin boş olup olmadığını sınar. Küme boş değilse
tanı gelir ve içindeki değer tanının metnine yazılır.
Bu kalıbın değeri, birleşime yeni bir durum eklendiğinde ortaya çıkar. Durum tipine
dördüncü bir değer eklenirse, o değeri ele almayan her switch bloğu derleme anında
hata verir. Tip sistemi burada bir bakım aracına dönüşür: modelin değişmesi, modeli
kullanan tüm kodun gözden geçirilmesini zorunlu kılar.
Üç Tipin Yeri
Üçünün ilişkisi tek bir tabloda toplanabilir:
| Tip | Ona atanabilenler | Ona atananın gidebildiği yerler | Kullanım yeri |
|---|---|---|---|
any |
Her tip | Her tip | Kademeli geçişte geçici |
unknown |
Her tip | Yok (daraltma gerekir) | Sistem sınırı |
never |
Yok | Her tip | Tükenmişlik denetimi, dönmeyen fonksiyon |
Tablodaki ilk satır anyin neden bir tip değil bir kapı olduğunu gösterir: her iki sütunu
da dolu olan tek satırdır ve bu, hiçbir kısıt getirmediği anlamına gelir. unknown ile
never ise birbirinin karşıtıdır — biri her şeyi kapsar ve hiçbir şeye izin vermez, diğeri
hiçbir şeyi kapsamaz ve her yere gider.
any tamamen yasaklanmaz. JavaScript ile Birlikte Çalışma dersinde görüleceği gibi, tip
bilgisi olmayan bir kod tabanına kademeli geçişte geçici olarak gereklidir. Kural şudur:
any bir geçiş işaretidir, bir çözüm değil; kaldığı yer belgelenir ve daraltılır.
Özet
any, tip denetimini kapatır; her iki yönde atanabilir olduğu için hiçbir güvence taşımaz ve denetimsizliği yayar.- Örtük
anybir eksikliktir venoImplicitAnyseçeneğiyle bildirilir; açıkanybir karardır. unknownen üst tiptir: her değer ona atanır, o hiçbir tipe atanmaz; kullanılabilmesi için daraltılması gerekir.- Sistem sınırından gelen veri
unknownolarak alınır ve alan alan sınanarak modele girer;asyazımı bu sınamanın yerine geçmez. neveren alt tiptir: hiçbir değeri yoktur, her tipe atanır;switchbloklarında tükenmişlik denetimi için kullanılır.
Sonraki Adım
Buraya kadar tipler elle yazıldı. Oysa yukarıdaki örneklerin çoğunda derleyici, yazılmamış
tipleri kendiliğinden biliyordu: oku fonksiyonunun içindeki daraltma sonrası tipler,
nesne sabitinin alan tipleri, dizi elemanlarının tipi. Sonraki ders bu bilgiyi nereden
aldığını — tip çıkarımının kurallarını ve sınırlarını — ele alacak.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.