打字稿错误:无法将“数字”类型分配给“从不”类型

时间:2020-05-08 04:09:49

标签: javascript typescript

interface Opts {
  onFrame: () => void;
  onAudioSample: null;
  emulateSound: boolean;
  sampleRate: number;
}

class NES {
    constructor(opts: Opts) {
        this.opts = {
            onFrame() { },
            onAudioSample: null,
            emulateSound: true,
            sampleRate: 44100,
        }

        if (typeof opts !== "undefined") {
            let key: keyof Opts
            for (key in this.opts) {
                if (typeof opts[key] !== "undefined") {
                    // got err here
                    this.opts[key] = opts[key];
                }
            }
        }
    }
    opts: Opts
}

您可以在TS游乐场检查错误:here

打字稿:v3.8.3 err: Type 'number'无法分配给类型never。 我不明白为什么它是never类型。

3 个答案:

答案 0 :(得分:2)

您收到该错误,因为TypeScript无法推断this.opts[key]opts[key]是同一类型。如果您要掩盖=的每半部分:

  • opts[key]可以是Functionnullbooleannumber
  • this.opts[key]需要接收Functionnullbooleannumber 取决于key的值,我们不知道
  • Functionnullbooleannumber的唯一共同的超类型是never, 这就是TypeScript想要的this.opts[key]
  • 类型

有趣的是,如果要将其提取到匿名泛型函数中,它将起作用:在单个赋值中,Typescript 可以推断并使用类型Opts[K]jcalzthis similar question中提出了类似的解决方案。

if (typeof opts[key] !== "undefined") {
  // this.opts[key] = opts[key];
  (<K extends keyof Opts>(k: K) => { this.opts[k] = opts[k]; })(key);
}

typescript playground

也就是说,我将像Mukesh Soni's answer中那样使用散布运算符,以this.opts结束对...opts的赋值,或者使用Object.assign。传递的opts包含额外的键会有一点风险,但是Typescript应该在编译时确保否则。 (因此,如果您期望opts是可选的并且可能不完整,则应将其定义为opts?: Partial<Opts>。)

class NES {
    constructor(opts?: Partial<Opts>) {
        this.opts = Object.assign({
            onFrame() { },
            onAudioSample: null,
            emulateSound: true,
            sampleRate: 44100,
        }, opts);
    }
    opts: Opts
}

另请参见: Object spread vs. Object.assign,它指出解决方案非常相似,并且都适用于默认选项值。

答案 1 :(得分:1)

我不知道您为什么会收到该错误。合并这两个选项的另一种方法可能是使用扩展运算符。

this.opts = {
            onFrame() { },
            onAudioSample: null,
            emulateSound: true,
            sampleRate: 44100,
            ...opts
        };

答案 2 :(得分:0)

如果在属性访问之后放置as any,TypeScript将检查key是有效的密钥

if (typeof opts[key] !== "undefined") {
  (this.opts[key] as any) = opts[key];
}