typescript - Tür daraltma: noUncheckedIndexedAccess doğru olduğunda değişken nesne anahtarı varlığını kontrol etme


tsconfig.json dosyamda "noUncheckedIndexedAccess": true var. Bu seçeneğin amacı, bir index'teki öğeye erişmeden önce varlığının kontrol edilmesini zorunlu kılmaktır.

👉 Değişken anahtarı olan bir nesne için kontrol yapmaya çalışıyorum:

Diyelim ki aşağıdaki yapıya sahibim:

const items: Record<string, {name: string}> = {
  '123': {
    name: 'asdf'
  }
}

Bir literal anahtar kullanarak varlığı kontrol etmeye çalıştığımda, tür daraltma düzgün çalışıyor:

if (items['123']) {
  // OK: Compiles no problem
  console.log(items['123'].name)
}

Eğer varlığı bir değişken anahtar kullanarak kontrol etmeye çalışırsam, derleyici şikayet etmeye başlıyor.

const id = '123';
if (items[id]) {
  // ERROR: items[id] - Object possibly undefined
  console.log(items[id].name)
}

👉 Varlığın bu şekilde kontrol edilmesi neden mümkün değil?

Hatta farklı kontroller denedim:

if (id in items) {}
if (items.hasOwnProperty(id)) {}
if (typeof items[id] !== 'undefined') {}

orada şans yok.

İşe yarayan tek şey

const id = '123';
const item = items[id];
if (item) {
  // OK
  console.log(item.name)
}

Ama bunu biraz fazla geveze buluyorum.

▶️ Yukarıdaki örnekler TypeScript Oyun Alanında

Ortam: TypeScript v4.5.4

Cevap #1

GitHub'da bu tam durumu esas olarak tanımlayan bir sorun var:

--noUncheckedIndexedAccess kullanırken, T | undefined değerini yanlışlık kontrolü ile T türüne daraltamıyor

Bu konu, Şubat 2022 itibarıyla hâlâ açık olan bu konunun tekrarı olarak kapatıldı:

Köşeli parantez gösterimiyle ayrımcı özellik tür koruyucusu uygulanmadı

O ikinci konu ve diğer bağlantılı konular hakkındaki tartışmaya dayanarak, bunun tip denetleyicide uygulanması için gereken performans yükünden dolayı bilinen bir sınırlama gibi görünüyor, örneğin burada:

Performans nedenleriyle reddedildi. Neredeyse her zaman yerine const j=list[i] yazmak mümkün olacağından, bu çok zahmetli olmamalı.

Sorunun hâlâ açık olması göz önüne alındığında, bu davranışı desteklemek için bir noktada tekrar ele alınması mümkün görünüyor.

İlgili makaleler