簡體   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