網站搜尋

如何在 TypeScript 中忽略「缺少以下屬性」錯誤?


我這樣創建了一個物件。

interface obj {
  x: number;
  y: number;
  deep?: {
    z: number;
  };
}

let obj: obj = {}; // Type '{}' is missing the following properties from type 'obj': x, y 
    ^^^

我可以使用可選欄位。但當我想要存取可選欄位時,我必須使用 nullish 運算子。

// But I don't want to use nullish operator
obj.deep?.z; 

// without nullish operator.
obj.deep.z;  // Object is possibly 'undefined'.
^^^^^^^^
// this is valid unless some condition (like is async function where its not "undefined" anymore);

因為可選欄位需要空值運算子。我需要某種方式來忽略「必須屬性」的類型錯誤。

答案#1

你可以使用類型斷言告訴編譯器你的值 {} 是一個 obj:

let obj = {} as obj;

類型斷言在你比編譯器更了解某個值的類型時非常有用。你只需要告訴編譯器你對這個值的認識,編譯器就會相信你(有時這需要額外的斷言,例如 as unknown as obj,但最終你可以讓編譯器相信你)。這將維持類型安全的責任從編譯器轉移到了你身上。由於編譯器只是相信你,它不會檢查你是否對它說謊。值 {} 並不是一個有效的 obj,因此通過使用類型斷言來表示它是,你就是在對編譯器說謊。

這並不像我說的那麼糟;如果你打算立即初始化 obj,這樣當其他人與它互動時,它將是一個正確的 obj 實例,那麼這就是一個善意的謊言。你只是希望編譯器在你初始化變量時“視而不見”:

let obj = {} as obj; // this is a lie
// DANGER ZONE
obj.x = 1;
obj.y = 2;
obj.deep = {} as { z: number };
obj.deep.z = 123;
// END DANGER ZONE
// obj is no longer a lie
obj.deep.z.toFixed(); // no error

但是你應該對這種方法小心。如果你沒有正確初始化變數,那麼在運行時就會出現問題。出於這個原因,我通常會嘗試重構我的代碼,以避免有一段時間它只是部分配置的狀態:

let badObj = { x: 1, y: 2 }
let deep = { z: 3 }; // get this from somewhere else, awaited or whatever
let goodObj: obj = Object.assign(badObj, { deep }); // okay

遊樂場連結