在TypeScript中,“object”、“{}”和“Object”的区别是什么?

114
尝试弄清 TypeScript 中这两种类型的区别: foo: objectbar: {} 以及 type: Object
例子: 尝试将一个 object 分配给变量,该变量应该处理请求的头信息:
headers: object;

产生错误的结果:

类型“object”不能赋给“{[key: string]: string}”。

如果使用headers: {},相同的条件会通过,这表明{}的要求稍微宽松一些。


我在想是否有任何的,因为似乎没有。 - H.B.
在某些情况下,TypeScript 会为其中一个触发错误。因此可能会有一些错误。 - 0leg
它们是可互相赋值的,因此请将您所知道的任何此类错误情况添加到问题中。 - H.B.
2个回答

136
TypeScript有三个容易混淆的类型:Object{}object
如果禁用strictNullChecks编译选项,则可以将nullundefined分配给这三种类型,否则会出现编译错误。

Object

Object包含所有JavaScript对象中存在的内容(例如toString()hasOwnProperty())。任何值(原始值、非原始值)都可以分配给Object类型。

{}

{}是一个空对象,在运行时与Object基本相同,但在编译时不具有Object的成员,而Object具有更严格的行为(请参见@golmschenk的评论)。

object

object 在TypeScript 2.2中引入。它是非原始类型。您无法将任何原始类型(如boolnumberstringsymbol)分配给它。
因此,如果尝试执行以下操作:
var strictTypeHeaders: { [key: string]: string } = {}; // non-primitive type
var header: object = {};
header = strictTypeHeaders; // its OK
strictTypeHeaders = header; // causes error "Type 'object' is not assignable to type '{ [key: string]: string }`"

你会在最后一行遇到编译错误。这是因为{ [key: string]: string }类型比object类型更具体。在header = strictTypeHeaders中没有任何错误,因为两种类型都是非原始类型,而object是比{ [key: string]: string }更常见的类型。


8
请不要使用“任何对象(原始、非原始、null等)”,而是用“任何值”。原始类型不是对象。 - Bergi
2
好的回答。如果有参考网址的话,那就更好了。 - 0leg
在TS中,如果一个函数参数的类型是:{ },那么我不能使用null值调用该函数。这似乎与上面的内容相矛盾。 - ttugates
7
Object{}并不完全相同。内置方法对于Object有预定义的强制类型,但没有对{}进行强制类型定义。因此,let x: {} = { toString() { return 2 } }将会运行,但是let x: Object = { toString() { return 2 } }将导致错误(因为toString要求在Object中返回字符串,但在{}中不需要返回字符串)。 - golmschenk

81
以下示例说明不同类型的对象的行为不同:
var o: object;
o = { prop: 0 }; // OK
o = []; // OK
o = 42; // Error
o = "string"; // Error
o = false; // Error
o = null; // Error
o = undefined; // Error

var p: {}; // or Object
p = { prop: 0 }; // OK
p = []; // OK
p = 42; // OK
p = "string"; // OK
p = false; // OK
p = null; // Error
p = undefined; // Error

var q: { [key: string]: any };
q = { prop: 0 }; // OK
q = []; // OK
q = 42; // Error
q = "string"; // Error
q = false; // Error
q = null; // Error
q = undefined; // Error

var r: { [key: string]: string };
r = { prop: 'string' }; // OK
r = { prop: 0 }; // Error
r = []; // Error
r = 42; // Error
r = "string"; // Error
r = false; // Error
r = null; // Error
r = undefined; // Error

因此,我们可以得出以下结论:

  • {} 表示的类型是 Object,最不具体。你可以将对象、数组和基本数据类型赋值给它。
  • object 更加具体,类似于 { [key: string]: any }。你可以将对象和数组赋值给它,但不能将基本数据类型赋值给它。
  • { [key: string]: string } 是最具体的类型,它不允许任何基本数据类型、数组或值为非字符串的对象被赋值给它。

TypeScript 演示链接


2
请注意,在所有这些情况下,console.log(typeof o)的结果都是“object”。 - serge

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接