TypeScript中object、{}与Object三种类型有何差异?
object、{}和Object的类型差异详解 刚好之前踩过这几个类型的坑,结合你提到的请求头赋值报错的场景,给你把这三个类型的区别拆解明白:
1. object类型
这个类型的核心是只代表非原始类型——也就是排除了string、number、boolean、symbol、null、undefined之外的所有值(比如普通对象、数组、函数都属于object类型)。
但它的局限性非常明显:TypeScript只知道这个值是个对象,但完全不知道它有哪些属性。所以当你声明let headers: object,然后试图给它赋值一个明确结构的{ [key: string]: string }对象时,就会出现你遇到的报错:Type 'object' is not assignable to '{ [key: string]: string }'。本质上是因为object太宽泛,但又没有提供任何属性的类型信息,TypeScript无法确认这个对象符合你需要的键值对结构。
2. {}类型
这是空对象类型,它的范围比object要宽松一点——它接受所有可以被当作对象的类型,包括原始类型的装箱值(比如你可以把字符串"test"赋值给let x: {},因为JavaScript会自动把它装箱成String对象)。
不过它和object有同样的问题:没有定义任何具体的属性,所以当你给它赋值请求头这种有明确键值对的对象时,同样会触发类型不匹配的报错。但你说的“约束略宽松”是对的,毕竟它允许原始类型的装箱值,而object完全不接受原始类型相关的值。
3. Object类型
这是全局Object构造函数对应的类型,它和{}几乎是等价的,甚至可以看作是{}的超集。它包含所有的对象类型,包括普通对象、数组、函数,以及原始类型的装箱对象(String、Number、Boolean等)。
同样的,它也无法用来约束有特定结构的对象,比如你的请求头——因为它没有描述任何属性的类型信息。
针对你的场景的正确做法
如果你需要处理请求头这种有明确结构{ [key: string]: string }的变量,用上面三个类型都不合适,应该直接定义对应的类型别名或者接口:
// 类型别名方式 type RequestHeaders = { [key: string]: string }; let headers: RequestHeaders = { 'Content-Type': 'application/json', 'Authorization': 'Bearer token' }; // 接口方式 interface RequestHeaders { [key: string]: string; }
这样TypeScript就能准确识别对象的结构,不会再出现类型不匹配的报错。
三者核心差异总结
object:仅接受非原始类型,拒绝原始类型及其装箱值,无属性访问权限。{}:接受所有可被视为对象的值(含原始类型装箱值),无属性访问权限。Object:与{}基本一致,是全局构造函数类型,范围最广。
内容的提问来源于stack exchange,提问作者0leg

