typescript - Vlastnosť proxy v setteri má typ nikdy (s MRE)


S TypeScript 4.5.4 (aktuálna najnovšia verzia) tento kód (pozri nižšie alebo v TypeScript playground) vyhadzuje chybu Type 'any' is not assignable to type 'never'.(2322) pre verzie 1, 2, 3, 4, no pre verzie 5 a 6 sa žiadna chyba nezobrazuje. Ak odstránime jeden z atribútov num alebo str, všetky chyby zmiznú.

Existuje vysvetlenie pre tento dizajn?

const myObj = {
  num: -1,
  arr: [1, 2, 3],
  str: '',
};

const proxy = new Proxy(myObj, {
  set(target, prop: keyof typeof myObj, value) {
    /* none of these works */
    // Ver. 1
    if (prop in target) target[prop] = value;
    // Ver. 2
    target[prop] = value;
    // Ver. 3
    target[prop as keyof typeof myObj] = value;
    // Ver. 4
    switch (prop) {
      case 'num':
      case 'str':
        target[prop] = value;
        break;
    }

    /* while these works */
    // Ver. 5
    switch (prop) {
      case 'num':
        target[prop] = value;
        break;
      case 'str':
        target[prop] = value;
        break;
    }
    // Ver. 6
    switch (prop) {
      case 'num':
        target[prop] = value;
        break;
      default:
        target[prop] = value;
        break;
    }

    return true;
  },
});

console.log('proxy : ', proxy);

Odpoveď č. 1

Zhrnuté

Písanie produkuje prienik typov v TS.

Podrobný

Toto je kópia odpovede z oficiálneho repozitára microsoft/TypeScript#47295, toto je funkcia, ktorá „funguje podľa očakávania“.

Vo väčšine vašich nastavení typ prop nie je zužovaný z "num" | "str" | "arr"; keďže zapisujete do target[prop] namiesto čítania z neho, produkuje to prienik (nie zjednotenie) všetkých možných typov, na ktoré sa môže odkazovať. Ak neexistuje žiadna zhoda, prienik sa zhroutí na never, pretože neexistuje žiadna hodnota, ktorá by fungovala pre všetky z nich.

Táto odpoveď je vytvorená na uzavretie otázky.