TypeScript 中令人迷惑的物件型別:Object、{} 和 object

deepfunc發表於2022-06-18

Object{}object,這三個表示物件的型別很容易讓人迷惑,下面來總結一下它們的聯絡和差異。

Object

ObjectObject.prototype 的介面定義。原始碼中定義如下:

interface Object {
  constructor: Function;
  toString(): string;
  toLocaleString(): string;
  valueOf(): Object;
  hasOwnProperty(v: PropertyKey): boolean;
  isPrototypeOf(v: Object): boolean;
  propertyIsEnumerable(v: PropertyKey): boolean;
}

JS 中所有物件的原型鏈預設都繼承自 Object.prototype,原始值有包裝型別。所以 numberstringbooleansymbol、物件和函式都可以賦值給 Object 型別。

{}

在 JS 中 {} 表示沒有自身屬性的字面量物件。但在 TS 中 {} 型別表示物件型別,能賦值給 Object 型別的值給都可以賦值給 {} 型別。但是這兩種型別還是有區別的,賦值給 Object 型別的物件必須嚴格滿足 Object.prototype 介面定義,而賦值給 {} 型別則無此限制。如下:

// toString() 必須嚴格滿足 Object.prototype.toString() 的定義,返回 string 型別。
// 這裡會報錯:Type '() => number' is not assignable to type '() => string'.
let a: Object = {
  toString() {
    return 1;
  }
};

let b: {} = {
  toString() {
    return 1;
  }
};

object

為表示非原始值型別的物件,TypeScript 2.2 中引入了 object 型別。除了 numberstringbooleansymbolnullundefined, 其他所有型別都可以賦值給 object 型別。所以按照 TS 的建議,當我們需要表示物件時,用 object 就好,基本可以不用 Object 和 {} 了。

object is not Object. Always use object!

我的 JS 部落格:小聲比比 JavaScript

相關文章