简体   繁体   中英

Proxy property in setter has never type

With TypeScript 4.5.4 (current latest) and currently Nightly version, this code (see below or in TypeScript playground ) is throwing error Type 'any' is not assignable to type 'never'.(2322) for the version 1,2,3,4 yet for version 5 and 6 no error is reported. If we remove one of the num prop or str , all the errors are gone.

Is there an explanation for this design?

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);

Summarized

Writing produces type intersection in TS.

Detailed

This is a copy of the answer from the official repo microsoft/TypeScript#47295 , this is a functionality that "work as intended".

In most of your setups, the type of prop is not narrowed down from "num" | "str" | "arr" "num" | "str" | "arr" "num" | "str" | "arr" ; since you're writing to target[prop] rather than reading from it, that produces an intersection (not a union) of all the possible types it could refer to. If there's no overlap, the intersection collapses to never , because there's no possible value that works for all of them.

This answer is created to close the question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM