繁体   English   中英

Typescript 错误:类型 'number' 不可分配给类型 'never'

[英]Typescript error:Type 'number' is not assignable to type 'never'

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 playground 上查错: 这里

typescript:v3.8.3 err: Type 'number'不可分配给类型never 我不明白为什么它是never类型。

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

  • opts[key]可以是Functionnullbooleannumber
  • this.opts[key]需要接收一个Functionnullbooleannumber ,具体取决于key的值,我们不知道
  • the only supertype in common for Function , null , boolean , and number is never , so that's the type that TypeScript wants for this.opts[key]

有趣的是,如果您要将其提取为匿名通用 function,它可以工作:在单个分配中 Typescript可以推断和使用类型 Opts Opts[K] jcalz这个类似的问题中提出了类似的解决方案。

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

typescript游乐场

也就是说,我会像Mukesh Soni 的回答那样使用扩展运算符,用...opts结束你对this.opts的分配,或者使用Object.assign 传递的选项包含额外密钥的风险很小,但opts应在编译时确保否则。 (就此而言,如果您希望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 ,其中指出解决方案非常相似并且都适用于默认选项值。

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

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

如果您在属性访问后放置as any ,TypeScript 将检查该key是否为有效密钥

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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