any ve unknown her değeri kabul eder. Fark, sonrasında değerle neler yapabileceğinizdedir: any her şeyi yapmanıza izin verir ve hiçbir şeyi kontrol etmez; unknown ise değerin ne olduğunu kanıtlayana kadar neredeyse hiçbir şey yapmanıza izin vermez.
@ts-expect-error satırı olmadan u.toUpperCase() TS18046 derleme hatasıdır. typeof kontrolü u değerini string tipine daraltır ve o blok içinde her string metodu kullanılabilir.
Bir Bakışta any ve unknown
any | unknown | |
|---|---|---|
| Her değeri kabul eder | evet | evet |
Bir string, number, ... değişkenine atanabilir | evet, kontrolsüz | hayır (TS2322) |
| Özellik okuma, metot çağırma | evet, kontrolsüz | hayır (TS18046) |
| Fonksiyon olarak çağırma | evet | hayır |
Aritmetik ve karşılaştırma (x * 2, x + 1, x < 5) | evet | hayır (TS18046) |
| Kullanmadan önce kontrol gerekir | hayır | evet (typeof, instanceof, in, bir type guard) |
| Tip kontrolüne etkisi | o değer ve dokunduğu her şey için kapanır | açık kalır |
Tip teorisi açısından unknown en üst tiptir (top type): her tip ona atanabilir, o ise yalnızca unknown ve any tiplerine atanabilir. any ise iki yönde de atanabilen bir kaçış kapısıdır; never dışında her şeye atanabilir.
any Tip Kontrolünü Kapatır
any tipindeki bir değere körü körüne güvenilir. Derleyici yazım hatalarını, yanlış tipleri ve eksik özellikleri kabul eder; hatalar da bunun yerine çalışma zamanında ortaya çıkar.
Çıktı sorunu gösteriyor: number notasyonlu bir değişken bir string tutuyor ve son satır Cannot read properties of undefined (reading 'city') fırlatıyor. any ayrıca yayılır. user.name bir any değeridir, bu yüzden ondan hesaplanan her değer de any olur ve tipsiz tek bir değer, girdiği yerden çok uzakta kontrolü kapatabilir.
unknown Önce Kontrol Etmenizi İster
unknown ile derleyici, kod değeri daraltana kadar her işlemi reddeder. Daraltma sıradan JavaScript kontrollerini kullanır ve her dalın içinde değer kontrol edilen tipe sahiptir.
value === null kontrolü nesne kontrolünden önce gelmelidir, çünkü typeof null sonucu "object" olur. "id" in value sonrasında TypeScript nesnenin bir id özelliğine sahip olduğunu bilir; ne tuttuğunu söyleyen bir şey olmadığı için tipi unknown olur. String() onu açıkça metne çevirir; sayı olarak kullanmak için önce typeof ile kontrol etmeniz gerekirdi.
Kontrolü bir assertion ile de atlayabilirsiniz, value as string, derleyici bunu kabul eder. Bu, arkasında çalışma zamanı kontrolü olmayan bir sözdür; gerçek bir kontrolü tercih edin, bkz. type assertion'lar.
unknown ile JSON Doğrulamak
JSON.parse, any döndürecek şekilde bildirilmiştir, bu yüzden sonucu kontrolü sessizce devre dışı bırakır. Sonuca unknown notasyonu yazın ve kodun geri kalanı ona güvenmeden önce biçimini kontrol eden bir type guard yazın.
İlk girdi dark at 14px yazdırır, ikincisi fontSize eksik olduğu için reddedilir. any ile ikinci girdi, fontSize değeri undefined olan bir Settings olarak akıp giderdi. Büyük şemalar için bir doğrulama kütüphanesi aynı işi yapar ve tipi sizin için türetir.
noImplicitAny
any yalnızca birinin onu yazmasından gelmez. Notasyonu olmayan ve çıkarım yapılacak bağlamı bulunmayan bir parametre de any olurdu. strict tarafından açılan noImplicitAny seçeneği bunu bir hata olarak bildirir:
index.ts(2,17): error TS7006: Parameter 'x' implicitly has an 'any' type.
Çözüm bir notasyondur, function double(x: number). Açıkça x: any yazmak da derlenir; amaç da budur: any kodda görünür kalır, aranabilir ve incelenebilir.
any'nin Hâlâ Sızdığı Yerler
strict altında bile şunlar, kodunuzda bu kelime görünmeden any üretir:
| Kaynak | Ne elde edersiniz | Ne yapmalı |
|---|---|---|
JSON.parse(text) | any | unknown notasyonu yazın, sonra doğrulayın |
Tarayıcı (DOM) tipleriyle response.json() | Promise<any> | JSON.parse ile aynı (Node'un kendi fetch tipleri zaten Promise<unknown> döndürür) |
| Tip tanımları olmayan bir paket | import'ları için any (bir bildirim eklemezseniz hatayla birlikte) | @types/... kurun ya da bir .d.ts yazın |
value as any | any | bir type guard ya da kesin bir assertion kullanın |
useUnknownInCatchVariables kapalıyken catch (e) | any | strict onu unknown yapar; öyle bırakın |
strict altında catch değişkeni unknown olur, çünkü yalnızca Error nesneleri değil, her şey fırlatılabilir. e.message okumadan önce onu e instanceof Error ile daraltın.
any Ne Zaman Kabul Edilebilir
any yasak değildir, ama her biri derleyicinin artık korumadığı bir noktadır. Makul kullanımlar:
- Bir JavaScript kod tabanını taşırken,
anyhenüz tiplenmemiş yerleri işaretler. - Tip sisteminin iyi ifade edemediği kod; küçük tutulur ve tipli bir fonksiyon imzasının arkasında kalır.
- Bilerek hatalı veri gönderen test kodu.
Geri kalan her şey için unknown, kontrolleri koruyarak aynı "bu tipi bilmiyorum" durumunu karşılar. Pek çok ekip bunu @typescript-eslint/no-explicit-any lint kuralıyla zorunlu kılar. İlgili bir tip olan Record<string, unknown> ise "değerleri bilinmeyen bir nesne" için alışılmış seçimdir.
Sıkça Sorulan Sorular
TypeScript'te any ile unknown arasındaki fark nedir?
İkisi de herhangi bir değeri kabul eder. any ile değerle her şeyi yapabilirsiniz (özellik okumak, çağırmak, bir number değişkenine atamak) ve derleyici hiçbir şeyi kontrol etmez. unknown ile ise typeof x === "string" gibi bir kontrolle daraltana kadar neredeyse hiçbir şey yapamazsınız. unknown tip kontrolünü açık tutar; daha güvenli seçim olmasının nedeni budur.
any yerine ne zaman unknown kullanmalıyım?
Bir değerin tipi derleme zamanında bilinmediğinde: ayrıştırılmış JSON, bir ağ yanıtından gelen veri, yakalanan bir hata, bir doğrulama fonksiyonunun girdisi. Onu unknown olarak tipleyin ve daraltın. any tipine yalnızca kısa vadeli taşıma çalışmalarında ya da tip sisteminin tanımlayamadığı kodlarda başvurun.
"Object is of type 'unknown'" ne anlama geliyor?
TS18046 ('x' is of type 'unknown') ve TS2571 (Object is of type 'unknown', değer load().id gibi düz bir ad olmadığında kullanılır) hataları, bir unknown değeri belirli bir tipi varmış gibi kullandığınızı gösterir; örneğin bir özellik okuyarak ya da bir metot çağırarak. Önce tipi kontrol edin (typeof, instanceof, Array.isArray, in veya bir type guard fonksiyonu) ve değeri daraltılmış dalın içinde kullanın.
JSON.parse neden any döndürüyor?
Standart kütüphanedeki bildirimi parse(text: string, ...): any şeklindedir, çünkü derleyici bir string'in ne içerdiğini bilemez. Sonuç, dokunduğu her şey için kontrolü sessizce kapatır. Bunun yerine notasyon yazın: const data: unknown = JSON.parse(text), sonra kullanmadan önce doğrulayın.
noImplicitAny nedir?
strict kapsamında bir derleyici seçeneğidir; notasyonu olmadığı ve çıkarılacak bir şey bulunmadığı için bir bildirim sessizce any tipini alacaksa hata bildirir: bir parametre için TS7006, tipi bulunamayan bir değişken için TS7005 veya TS7034. Kimse yazmadan any ortaya çıkmasını engeller. Açıkça yazılan any yine de serbesttir.