strictNullChecks açıkken (strict kapsamındadır) null ve undefined kendi tipleridir. Bir string asla null olamaz; eksik olabilecek bir değer bunu string | null gibi tipinde belirtmek zorundadır ve TypeScript değeri kullanmadan önce bu durumu ele almanızı ister.
Kontrolden sonra derleyici name değerinin bir string olduğunu bilir, bu yüzden .split kullanılabilir. Bu sayfanın geri kalanı, bu kontrolü yapmanın yollarını ve onu kısaltan operatörleri anlatıyor.
strictNullChecks ve "Possibly Null" Hataları
Bir tip null veya undefined içerdiğinde TypeScript değeri her zaman oradaymış gibi kullanmayı reddeder:
index.ts(3,22): error TS18047: 'name' is possibly 'null'.
undefined sürümü TS18048'dir, 'x' is possibly 'undefined'. strictNullChecks olmadan null ve undefined her tipte serbesttir; bu kod derlenir ve name ilk kez null olduğunda çalışma zamanında bir TypeError ile çöker. strict seçeneğini açık tutmanın asıl nedeni bu hata sınıfıdır.
Bu tiplerin günlük kodda nereden geldiği:
| Kaynak | Tip |
|---|---|
arr.find(...) | T | undefined |
map.get(key) | V | undefined |
opsiyonel özellik p?: T | okunduğunda T | undefined |
opsiyonel parametre x?: T | fonksiyonun içinde T | undefined |
str.match(re) | RegExpMatchArray | null |
JSON.parse(text) | any, yani hiçbir şey kontrol edilmez |
null ve undefined Kontrolü
Aşağıdaki her kontrol blok içinde tipi daraltır. Elemek istediğiniz şeye uyanı seçin.
| Kontrol | Tipten çıkardığı |
|---|---|
x !== undefined | undefined |
x !== null | null |
x != null | null ve undefined |
typeof x !== "undefined" | undefined |
if (x) | null ve undefined, ayrıca 0, "", false, NaN değerlerini de atlar |
== null, gevşek eşitliğin alışılmış olduğu tek yerdir: yalnızca null ve undefined için true olur, başka hiçbir şey için değil. Bir truthiness kontrolü boş string'i eksik sayardı; bu da çoğu zaman bir hatadır.
Optional Chaining: ?.
a?.b, a değeri null veya undefined değilse b özelliğini okur, aksi halde durur ve undefined döndürür. Aynı operatör indeksler için a?.[i], çağrılar için fn?.() şeklinde çalışır.
bob.address?.city ifadesinin tipi string | undefined olur: optional chaining sonuca undefined ekler, bu yüzden onu genellikle ?? ile birlikte kullanırsınız. Çalışma zamanındaki davranış düz JavaScript'tir; kısa devrenin ayrıntıları için optional chaining sayfasına bakın.
Çift Soru İşareti: ??
a ?? b, a değeri null veya undefined değilse a, öyleyse b döndürür. 0, "", false ve NaN değerlerini de atan eski a || b kalıbının yerini alır:
| Sol değer | left || "d" | left ?? "d" |
|---|---|---|
null | "d" | "d" |
undefined | "d" | "d" |
0 | "d" | 0 |
"" | "d" | "" |
false | "d" | false |
NaN | "d" | NaN |
Tipler açısından ??, sol taraftan null ve undefined tiplerini çıkarır ve kalanı sağ tarafla birleştirir (union); scores.get("Linus") ?? 0 ifadesinin bir number değişkenine atanabilmesinin nedeni budur.
Nullish Atama: ??=
a ??= b, b değerini a değişkenine yalnızca a değeri null veya undefined olduğunda atar. Kardeşleri ||= ve &&= ise sol taraf falsy veya truthy olduğunda atar.
retries: 0, ??= işleminden sağ çıkar; boş label ise ||= tarafından değiştirilir. opts.retries ??= 3 sonrasında TypeScript, fonksiyonun geri kalanında opts.retries değerini number tipine daraltır.
Opsiyonel Özellikler ve | undefined
nickname?: string ile nickname: string | undefined okunurken aynıdır, ama anahtarın var olması gerekip gerekmediğinde ayrılırlar:
Çağıranlar özelliği atlayabilecekse ?, her çağıranın değeri undefined olsa bile onu açıkça vermesini istiyorsanız | undefined kullanın. exactOptionalPropertyTypes seçeneği (strict kapsamında değildir) ? işaretini daha da sıkılaştırır: nickname?: string o durumda { nickname: undefined } değerini reddeder ve yalnızca eksik bir anahtarı ya da bir string'i kabul eder. Opsiyonel fonksiyon parametreleri (x?: number) opsiyonel özellikler gibi davranır: fonksiyonun içinde x bir number | undefined olur.
null mı undefined mı: Hangisi Kullanılmalı
TypeScript bir seçim dayatmaz, ama bir kod tabanında ikisini karıştırmak her kontrolün iki durumu ele alması demektir. Yaygın bir gelenek:
- Kendi tiplerinizde "ayarlanmamış" için
undefined(ve opsiyonel özellikler) kullanın. JavaScript'in varsayılan olarak ürettiği budur: olmayan özellikler, verilmeyen argümanlar,findveMap.getıskaları. - Bir API size
nullveriyorsa onu kabul edin:JSONiçindeundefinedyoktur,String.prototype.matchve pek çok DOM metodunulldöndürür. - Bir değer ikisinden biri olabiliyorsa
== nullile kontrol edin.
Dizi indeksleme tek boşluktur: users[5], indeks aralık dışında olsa bile eleman tipiyle tiplenir. noUncheckedIndexedAccess seçeneği (strict kapsamında değildir) her indeks erişimine | undefined ekler, böylece derleyici bunu da yakalar.
Sıkça Sorulan Sorular
TypeScript'te çift soru işareti ne anlama gelir?
a ?? b, JavaScript'ten gelen nullish coalescing operatörüdür. a değeri null veya undefined değilse a döndürür, öyleyse b döndürür. || operatörünün aksine 0, "" ve false gibi diğer falsy değerleri korur. TypeScript sol tarafın tipinden null ve undefined tiplerini çıkarır; bu yüzden a bir string | undefined iken a ?? "x" ifadesi bir string olur.
TypeScript'te bir değerin undefined olup olmadığını nasıl kontrol ederim?
Karşılaştırın: if (value !== undefined) { ... }. TypeScript blok içinde tipi daraltır. Tek bir kontrolle hem null hem undefined değerini elemek için gevşek eşitlik olan value != null kullanın; ==/!= kullanımının alışılmış olduğu tek yer burasıdır. Bir truthiness kontrolü (if (value)) de daraltır ama 0, "" ve false değerlerini atlar.
"Object is possibly undefined" ne anlama gelir?
TS18048 ('x' is possibly 'undefined') ve TS18047 ('x' is possibly 'null') hataları, ya da değerin getUser().address.city gibi basit bir adı olmadığında TS2532 (Object is possibly 'undefined'), strictNullChecks kaynaklıdır: tip undefined veya null içerir ve kod değeri öyle olamazmış gibi kullanır. Önce kontrol edin, optional chaining (x?.name) kullanın, ?? ile bir varsayılan verin ya da değer gerçekten eksik olamıyorsa tipi değiştirin.
TypeScript'te null ile undefined arasındaki fark nedir?
Her biri tek değere sahip iki ayrı tiptir. JavaScript hiç ayarlanmamış şeyler için undefined kullanır (olmayan bir özellik, verilmeyen bir argüman, olmayan bir anahtar üzerinde Map.get), API'ler ise bilinçli bir "değer yok" için null kullanır (JSON, pek çok DOM metodu). TypeScript onları ayrı izler, bu yüzden string | null tipi undefined kabul etmez. Pek çok kod tabanı kendi kodu için undefined seçer ve null değerini yalnızca sınırlarda kabul eder.
Opsiyonel bir özellik | undefined ile aynı şey mi?
Tam olarak değil. name?: string özelliğin tamamen eksik olabileceği anlamına gelir ve onu okumak string | undefined verir. name: string | undefined ise değeri undefined olsa bile özelliğin var olması gerektiği anlamına gelir. exactOptionalPropertyTypes açıkken name?: string açıkça verilmiş bir undefined değerini de kabul etmez.