Vyhledávání na webu

typescript - Zúžení typu: kontrola existence klíče objektu proměnné, když je noUncheckedIndexedAccess pravda


Mám "noUncheckedIndexedAccess": true v mém tsconfig.json. Celý smysl tohoto přepínače je vynutit kontrolu existence položky na daném indexu před jejím přístupem.

👉 Mám problém provést kontrolu objektu s proměnným klíčem:

Řekněme, že mám následující strukturu:

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

když se pokusím zkontrolovat existenci pomocí literálního klíče, zužování typu funguje v pořádku:

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

Pokud se pokusím zkontrolovat existenci pomocí proměnného klíče, kompilátor začne stěžovat.

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

👉 Proč není možné zkontrolovat existenci tímto způsobem?

Zkoušel jsem i různé kontroly:

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

tam žádné štěstí.

Jediná věc, která fungovala, byla

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

Přijde mi to ale trochu příliš upovídané.

▶️ Příklady výše v TypeScript Playground

Prostředí: TypeScript v4.5.4

Odpověď č. 1

Na GitHubu je problém, který v podstatě popisuje tuto přesnou situaci:

Nelze zužovat T | undefined na T pomocí kontroly nepravdivosti při použití --noUncheckedIndexedAccess

Tento problém je uzavřen jako duplicitní k tomuto problému, který je stále otevřen k únoru 2022:

Ochrana typu vlastnosti diskriminantu nebyla použita u zápisu pomocí závorek

Na základě diskuse o tom druhém problému a dalších propojených problémech to zní, že se jedná o známé omezení kvůli výkonovému zatížení, které by bylo nutné k implementaci tohoto v kontroloru typů, např. zde:

Odmítnuto z důvodů výkonu. Protože by téměř vždy mělo být možné napsat const j=list[i] místo toho, nemělo by to být příliš zatěžující.

Vzhledem k tomu, že problém je stále otevřený, zdá se možné, že by mohl být v určitém okamžiku znovu řešen, aby podporoval chování, které očekáváte.

Související články