Salvo

WFN Üye
Konular
1,728
Mesajlar
1,750
Çözüm
0
Ticaret Puanı
0
Üyelik
6 Ay 16 Gün
Konum
İstanbul
Web Sitesi
Yok
Alanı
Belirtmemiş
1/1
Konu sahibi
İlk olarak hatanın nedenini ayırın: TypeScript, bir değişkenin null veya undefined olabileceğini biliyorsa, o değişkeni kontrol etmeden kullanmanıza izin vermez. Çözüm; değerin gerçekten zorunlu olup olmadığını belirlemek, zorunlu değilse kontrol veya varsayılan değer kullanmak, zorunluysa türü ve verinin üretildiği yeri düzeltmektir. Sadece hata mesajını susturmak için ! kullanmak ise değerin gerçekten mevcut olduğunu kanıtlamaz ve çalışma zamanında yeni bir hata oluşturabilir.

Hatanın temel nedeni: değer henüz mevcut olmayabilir​


null, bilerek boş bırakılmış bir değeri; undefined ise çoğunlukla henüz değer atanmamış, bulunamamış veya bir fonksiyonun değer döndürmemiş olmasını ifade eder. TypeScript’in strictNullChecks seçeneği etkin olduğunda, string türü yalnızca metin kabul eder; null ve undefined bu türe kendiliğinden dahil değildir.

Örneğin aşağıdaki kodda isim değişkeni bir metin veya undefined olabilir:

Kod:
function kullaniciAdiGetir(): string | undefined {
  return undefined;
}

const isim = kullaniciAdiGetir();
console.log(isim.toUpperCase());

Buradaki sorun, toUpperCase() çağrısının yalnızca gerçekten bir metin varsa güvenli olmasıdır. Fonksiyon undefined döndürürse JavaScript çalışma zamanında hata oluşur. TypeScript’in derleme aşamasında bu kullanımı engellemesi, hatayı çalıştırmadan önce fark etmenizi sağlar.

Değeri kullanmadan önce kontrol edin​


Değerin bulunmadığı durumda başka bir işlem yapılacaksa en güvenli yöntem açık bir kontrol yazmaktır:

Kod:
function kullaniciAdiGetir(): string | undefined {
  return undefined;
}

const isim = kullaniciAdiGetir();

if (isim !== undefined) {
  console.log(isim.toUpperCase());
} else {
  console.log("Kullanıcı adı bulunamadı.");
}

Bu örnekte if bloğunun içinde TypeScript, isim değişkeninin artık string olduğunu anlar. else bloğu ise değerin bulunamadığı durumu ayrıca ele alır. Bu kontrol, değerin mevcut olduğunu garanti eder; ancak verinin neden bulunamadığını açıklamaz. Değerin bir API yanıtından, formdan veya veritabanından gelmesi durumunda bu neden ayrıca incelenmelidir.

null ve undefined değerlerinin ikisini birden kontrol etmek istediğinizde eşitsizlik kontrolü kullanabilirsiniz:

Kod:
const aciklama: string | null | undefined = getAciklama();

if (aciklama != null) {
  console.log(aciklama.trim());
}

Buradaki != null ifadesi hem null hem de undefined değerlerini dışarıda bırakır. Bu kullanım, iki değeri tek tek karşılaştırmaktan daha kısadır. Ancak 0, false veya boş metin gibi geçerli değerleri de reddetmek istemiyorsanız if (aciklama) biçimindeki doğruluk kontrolünü gelişigüzel kullanmayın.

Değer yoksa varsayılan değer verin​


Değer bulunamadığında kullanılacak makul bir alternatif varsa ?? operatörünü kullanın:

Kod:
const kullaniciAdi: string | undefined = getKullaniciAdi();
const gorunenAd = kullaniciAdi ?? "Misafir";

console.log(gorunenAd.toUpperCase());

?? yalnızca sol taraftaki değer null veya undefined olduğunda sağdaki değeri kullanır. Bu nedenle 0, false ve "" gibi değerler korunur.

Buna karşılık || operatörü tüm falsy değerlerde sağdaki seçeneğe geçer:

Kod:
const sayfaBoyutu = 0;
const sonuc = sayfaBoyutu || 10; // 10
const digerSonuc = sayfaBoyutu ?? 10; // 0

Burada 0 geçerli bir değer olabiliyorsa || yanlış sonuç üretir. Varsayılan değer yalnızca boşluk durumunda kullanılacaksa ?? daha doğru seçimdir.

Aynı işi parametre için de yapabilirsiniz:

Kod:
function selamla(isim?: string): string {
  const kullanilacakIsim = isim ?? "Misafir";
  return `Merhaba ${kullanilacakIsim}`;
}

console.log(selamla());
console.log(selamla("Ayşe"));

İlk çağrıda parametre verilmediği için sonuç Merhaba Misafir olur. İkinci çağrıda verilen isim korunur. Bu çözüm, değerin yokluğunun uygulama açısından normal olduğu durumlar içindir; zorunlu bir kullanıcı adı veya kimlik için sessizce varsayılan değer vermek yanlış olabilir.

İç içe nesnelerde güvenli erişim kullanın​


Bir nesnenin kendisi veya içindeki alanlar bulunmayabiliyorsa, her seviyeyi ayrı ayrı kontrol etmek yerine isteğe bağlı zincirleme operatörünü kullanabilirsiniz:

Kod:
type Kullanici = {
  profil?: {
    sehir?: string;
  };
};

const kullanici: Kullanici = {};
const sehir = kullanici.profil?.sehir;

console.log(sehir ?? "Şehir bilgisi yok");

kullanici.profil?.sehir ifadesi, profil yoksa hata vermek yerine undefined üretir. Bu operatör hatayı çözmüş sayılmaz; yalnızca eksik veriyi güvenli biçimde undefined olarak taşır. Değer zorunluysa, devam eden kodda kontrol etmeniz veya açık bir hata üretmeniz gerekir.

Fonksiyon dönüş türünü ve erken dönüşleri düzeltin​


Bir fonksiyon her durumda değer döndürmüyorsa TypeScript bunu undefined ihtimali olarak değerlendirir. Aşağıdaki örnekte yalnızca koşul sağlanırsa değer döndürülür:

Kod:
function dosyaUzantisi(dosyaAdi: string): string {
  if (dosyaAdi.includes(".")) {
    return dosyaAdi.split(".").pop() as string;
  }

  // Koşul sağlanmadığında dönüş yok
}

Bu tür bir fonksiyonda tüm yolların aynı sonucu üretmesini sağlayın veya dönüş türünü açıkça genişletin. Değer bulunamaması beklenen bir durumsa string | undefined kullanıp çağıran yerde kontrol etmek daha doğrudur:

Kod:
function dosyaUzantisi(dosyaAdi: string): string | undefined {
  const noktaKonumu = dosyaAdi.lastIndexOf(".");

  if (noktaKonumu === -1 || noktaKonumu === dosyaAdi.length - 1) {
    return undefined;
  }

  return dosyaAdi.slice(noktaKonumu + 1);
}

const uzanti = dosyaUzantisi("rapor.pdf");

if (uzanti === undefined) {
  console.log("Dosyanın uzantısı yok.");
} else {
  console.log(`Uzantı: ${uzanti}`);
}

Burada undefined bir programlama kazası değil, fonksiyonun tanımlı sonucu olarak kullanılır. Çağıran kodun bu durumu ele alması gerekir. as string ile türü zorla string yapmak ise fonksiyonun gerçekten her zaman metin döndürmesini sağlamaz; yalnızca derleyiciye varsayımınızı bildirir.

Dizi aramalarında undefined sonucunu unutmayın​


find() gibi metotlar aranan öğeyi bulamazsa undefined döndürebilir:

Kod:
type Urun = {
  id: number;
  ad: string;
};

const urunler: Urun[] = [
  { id: 1, ad: "Klavye" }
];

const urun = urunler.find((oge) => oge.id === 2);

if (urun === undefined) {
  console.log("Ürün bulunamadı.");
} else {
  console.log(urun.ad);
}

Burada urun değişkenini doğrudan urun.ad biçiminde kullanmak güvenli değildir. Arama sonucunun boş olması, dizinin bozuk olduğunu kanıtlamaz; yalnızca verilen ölçüte uyan öğe bulunmadığını gösterir. Uygulama açısından ürünün bulunamaması hata ise kullanıcıya açıklama gösterebilir veya çağıran koda hata döndürebilirsiniz.

Tür tanımını verinin gerçeğine göre yazın​


Bir alanın gerçekten boş olabilmesi normal ise türüne bunu ekleyin:

Kod:
type Ayarlar = {
  tema: "acik" | "koyu";
  dil?: string;
};

function ayarDiliniGoster(ayarlar: Ayarlar): string {
  return ayarlar.dil ?? "tr";
}

Buradaki dil? alanın gönderilmesinin zorunlu olmadığını belirtir. Alan her zaman gelmek zorundaysa soru işaretini kaldırıp eksik veriyi kaynağında düzeltin. Türü gereksiz biçimde string | null | undefined yapmak, her kullanım noktasına ek kontrol taşır ve veri sözleşmesindeki problemi gizleyebilir.

API yanıtlarında da aynı ayrımı yapın. Sunucu alanı hiç göndermiyorsa undefined, alanı açıkça boş gönderiyorsa null alabilirsiniz. Bu iki durum uygulamanız için farklı anlama geliyorsa türü buna göre tanımlayın ve yanıtı kullanan kodda iki durumu ayrı ele alın.

Non-null assertion operatörünü yalnız kanıt varsa kullanın​


Aşağıdaki kullanım TypeScript hatasını susturur:

Kod:
const eleman = document.querySelector("#baslik");
eleman!.textContent = "Hazır";

! işareti, “Bu değer burada kesinlikle boş değil” varsayımını derleyiciye bildirir. Fakat DOM içinde #baslik bulunmuyorsa çalışma zamanında hata almaya devam edersiniz. Bu nedenle önce kontrol etmek daha güvenlidir:

Kod:
const eleman = document.querySelector("#baslik");

if (eleman === null) {
  throw new Error("#baslik elementi bulunamadı.");
}

eleman.textContent = "Hazır";

Bu örnekte kontrol başarısız olursa hata açık bir nedenle durur; başarılı olursa sonraki satırda eleman güvenli biçimde kullanılabilir. ! ancak değerin varlığı başka bir doğrulanmış koşulla gerçekten garanti ediliyorsa tercih edilmelidir.

Hangi çözümü seçmelisiniz?​


Sorunun kaynağına göre uygulanacak yaklaşım değişir:
DurumUygun yaklaşım
Değer normal olarak bulunmayabilirKontrol yazın veya ?? ile varsayılan değer verin.
Değer zorunlu olmalı, fakat eksik geliyorÜretildiği yeri, API yanıtını veya fonksiyon akışını düzeltin.
İç içe alanlar eksik olabilir?. ile güvenli erişin, ardından gerekirse ?? kullanın.
Dizi araması sonuç vermeyebilirfind() sonucunu undefined açısından kontrol edin.
Değerin kesinlikle mevcut olduğu kanıtlanmışGerekirse ! kullanılabilir; bunun çalışma zamanı kontrolü olmadığını unutmayın.
Tabloya göre karar verirken yalnız derleyici hatasını kaldırmayı değil, eksik değerin uygulamadaki anlamını dikkate alın. Kullanıcıya “bulunamadı” gösterilmesi gereken bir durumda varsayılan değer vermek sorunu gizleyebilir. Buna karşılık isteğe bağlı profil açıklaması gibi bir alanda varsayılan metin kullanmak doğru olabilir.

tsconfig ayarını kontrol edin​


Bu hataların görünmesi çoğu zaman strictNullChecks seçeneğinin etkin olmasından kaynaklanır. Bu seçenek, null ve undefined değerlerinin diğer türlerle karıştırılmasını sınırlar. Hatayı kapatmak için bu denetimi devre dışı bırakmak, mevcut kodu derletse bile çalışma zamanı hatalarını ortadan kaldırmaz.

Bu nedenle izlenecek sıra şöyledir:
  1. Hata verilen değişkenin türünde null veya undefined bulunup bulunmadığını okuyun.
  2. Değerin neden boş olabildiğini belirleyin: isteğe bağlı alan mı, başarısız arama mı, eksik dönüş mü, yoksa hatalı veri akışı mı?
  3. Değer normal olarak boş olabiliyorsa kontrol, ?? veya ?. kullanın.
  4. Değer zorunluysa onu üreten fonksiyon, API yanıtı veya koşul akışını düzeltin.
  5. Kodu derleyin ve yalnız derleme hatasının kaybolduğunu değil, boş değer durumunda beklenen davranışın oluştuğunu kontrol edin.
Derleme hatasının kaybolması tek başına verinin doğru geldiğini kanıtlamaz. Örneğin as string veya ! kullanımı yalnız TypeScript’in uyarısını kaldırabilir. Gerçek çözüm, boş değerin uygulama tarafından nasıl ele alınacağını açıkça belirlemektir.

Sık sorulan sorular​

null ile undefined arasındaki fark neden önemlidir?​

null çoğunlukla bilerek boş bırakılmış değeri, undefined ise değer atanmamasını veya bir sonucun bulunamamasını ifade eder. Uygulamanız bu iki durumu aynı kabul ediyorsa != null veya ?? yeterli olabilir. Farklı anlam taşıyorlarsa ikisini ayrı kontrollerle ele almalısınız.

Hata vermemesi için her yerde || kullanabilir miyim?​

Hayır. ||, 0, false ve boş metin gibi geçerli değerleri de yok kabul eder. Yalnızca null veya undefined için varsayılan değer gerekiyorsa ?? kullanın.

any kullanmak bu hatayı çözer mi?​

any, TypeScript’in tür denetimini büyük ölçüde devre dışı bırakır; değerin gerçekten mevcut olduğunu garanti etmez. Bu nedenle hata derleme aşamasında görünmeyebilir, fakat uygulama çalışırken devam edebilir. Sorunun kaynağını kontrol etmek genellikle daha güvenlidir.

Non-null assertion (!) ne zaman kullanılabilir?​

Değerin ilgili noktada kesinlikle mevcut olduğunu kod akışıyla kanıtlayabiliyorsanız kullanılabilir. Ancak ! çalışma zamanında kontrol yapmaz. Değer dış bir kaynaktan, DOM’dan veya API’den geliyorsa açık kontrol ya da hata yönetimi tercih edilmelidir.
 

Sende şimdi bize katılmak ister misin?

Kayıt ol

Bize katılım kolay ve ücretsizdir!

Foruma git ?

Bu konuyu görüntüleyen kullanıcılar

Bu konuyu şu anda görüntüleyen üye bulunmuyor.
Robotlar:
  • Anthropic