0023. object 类型和 Object 类型
- 1. 🎯 本节内容
- 2. 🫧 评价
- 3. 🤔 什么是 Object 类型(大写 O)?
- 4. 🤔 什么是 object 类型(小写 o)?
- 5. 🆚 Object vs. object
- 6. 🤔 使用 object 类型的最佳实践是什么?
1. 🎯 本节内容
- object
- Object
2. 🫧 评价
- object 和 Object 都不太常用,简单了解即可。
- 官方文档对 object 和 Object 的描述也不多(因为它们的约束太宽泛了,通常起不到太大的作用),更多的篇幅都是在介绍 interface 类型和 type 类型,以定义对象的具体类型。
3. 🤔 什么是 Object 类型(大写 O)?
Object是 JavaScript 内置的Object构造函数的类型,它代表所有对象的基类。- 大写的
Object类型代表 JavaScript 语言里面的广义对象。所有可以转成对象的值,都是Object类型,这囊括了几乎所有的值。 - 除了
undefined和null这两个值不能转为对象,其他任何值都可以赋值给 Object 类型。 - 特点:
- 包含原始类型:
Object类型实际上可以接受任何值,包括原始类型(string、number、boolean 等) - 过于宽泛:几乎等同于
any类型,但仍然保留一些类型检查 - 不推荐使用:因为它无法提供有效的类型安全
- 无所不包的
Object类型既不符合直觉,也不方便使用。
- 无所不包的
- 包含原始类型:
ts
// Object 类型可以接受任何值
let obj1: Object = 'hello' // ✅ 允许
let obj2: Object = 42 // ✅ 允许
let obj3: Object = true // ✅ 允许
let obj4: Object = { name: 'John' } // ✅ 允许
let obj5: Object = null // ❌ 错误(严格模式下)
let obj6: Object = undefined // ❌ 错误(严格模式下)
// 虽然可以赋值,但访问属性时会有问题
let str: Object = 'hello'
// str.length; // ❌ 错误:Property 'length' does not exist on type 'Object'1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
- 空对象
{}是Object类型的简写形式,所以使用Object时常常用空对象代替。
ts
let obj: {}
obj = true
obj = 'hi'
obj = 1
obj = { foo: 123 }
obj = [1, 2]
obj = (a: number) => a + 1
// 等效
let obj2: Object
obj2 = true
obj2 = 'hi'
obj2 = 1
obj2 = { foo: 123 }
obj2 = [1, 2]
obj2 = (a: number) => a + 11
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
不推荐使用 Object 类型的原因:
ts
// 不好的做法
function processItem(item: Object) {
// 无法确定 item 的具体结构
// 可能是字符串、数字或真正的对象
}
// 更好的做法
function processItem(item: object) {
// 确保 item 是真正的对象
}
// 或者使用更具体的类型
function processItem(item: Record<string, any>) {
// 明确表示这是一个键值对对象
}
// 如果能够明确具体的字段,更推荐直接使用 interface 或类型别名来明确具体的结构。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
4. 🤔 什么是 object 类型(小写 o)?
object是 TypeScript 2.2 引入的类型,专门表示非原始类型的值。- 小写的
object类型代表 JavaScript 里面的狭义对象,即可以用字面量表示的对象,只包含对象、数组和函数,不包括原始类型的值。 - 特点:
- 排除原始类型:不能是
string、number、boolean、symbol、null、undefined - 只接受对象:包括普通对象、数组、函数等
- 类型安全:提供更好的类型约束
- 排除原始类型:不能是
ts
// object 类型只能接受非原始类型
let obj1: object = { name: 'John' } // ✅ 允许
let obj2: object = [1, 2, 3] // ✅ 允许(数组是对象)
let obj3: object = () => {} // ✅ 允许(函数是对象)
let obj4: object = new Date() // ✅ 允许
// 对象、数组、函数都属于 object 类型
// 以下都会报错
let obj5: object = 'hello' // ❌ 错误
let obj6: object = 42 // ❌ 错误
let obj7: object = true // ❌ 错误
let obj8: object = null // ❌ 错误(开启 strictNullChecks 时)
let obj9: object = undefined // ❌ 错误(开启 strictNullChecks 时)1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
使用 object 类型的一些常见场景:
ts
// 函数参数需要确保传入的是对象而不是原始类型
function cloneObject(obj: object): object {
return { ...(obj as any) } // 注意:需要类型断言
}
// 更好的做法是使用泛型
function cloneObject<T extends object>(obj: T): T {
return { ...obj }
}
// 对象字面量类型
type Config = {
settings: object // 确保 settings 是对象而非字符串等
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
5. 🆚 Object vs. object
| 特性 | Object (大写) | object (小写) |
|---|---|---|
| 使用频率 | 低 | 低(但高于 Object) |
| 原始类型 | ✅ 允许 | ❌ 不允许 |
| 对象类型 | ✅ 允许 | ✅ 允许 |
| 类型安全 | 低(过于宽泛) | 高(精确约束) |
| 推荐使用 | ❌ 不推荐 | ✅ 推荐 |
| 引入版本 | TypeScript 1.0+ | TypeScript 2.2+ |
6. 🤔 使用 object 类型的最佳实践是什么?
- 优先使用
object:当你需要表示非原始类型的对象时 - 避免使用
Object:除非你有特殊需求 - 使用更具体的类型:如接口、类型别名、
Record等 - 结合泛型使用:提供更好的类型推断
ts
// 推荐的模式
function mergeObjects<T extends object, U extends object>(
obj1: T,
obj2: U
): T & U {
return { ...obj1, ...obj2 }
}
// 而不是
function mergeObjects(obj1: Object, obj2: Object) {
// 类型信息丢失
}1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12