在 TypeScript 中,对象(Object)是数据结构的核心概念之一。对象可以包含属性和方法,并且可以使用类型注解、接口、类型别名等方式进行定义和约束,从而提高代码的可读性、可维护性和类型安全性。
目录
- 什么是对象?
- 对象类型的定义方式
- 使用类型推断
- 使用类型别名
- 使用接口(
interface
)
- 可选属性和只读属性
- 索引签名
- 对象的方法
- 对象的嵌套与组合
- 对象的扩展(继承 & 交叉类型)
- 对象的类型断言
- 对象的深拷贝与浅拷贝
- 最佳实践
- 参考资料
1. 什么是对象?
在 TypeScript 中,对象是由键值对(key-value) 组成的数据结构,类似于 JavaScript 的对象:
const person = {
name: "Alice",
age: 25,
greet() {
console.log(`Hello, my name is ${this.name}`);
}
};
person.greet(); // 输出: Hello, my name is Alice
对象的特点:
- 属性(Properties): 以
key: value
的形式存储数据。 - 方法(Methods): 可以定义函数作为对象的方法。
2. 对象类型的定义方式
(1)使用类型推断
TypeScript 可以自动推断对象的类型:
const car = {
brand: "Tesla",
model: "Model S",
year: 2024
};
// car.brand = 123; // ❌ 报错,brand 只能是 string 类型
缺点: 无法复用类型定义。
(2)使用类型别名
使用 type
关键字定义对象类型:
type Car = {
brand: string;
model: string;
year: number;
};
const myCar: Car = {
brand: "Toyota",
model: "Camry",
year: 2022
};
(3)使用接口(interface
)
接口(interface
)也可以用于定义对象类型:
interface User {
username: string;
email: string;
}
const user: User = {
username: "john_doe",
email: "john@example.com"
};
接口 vs. 类型别名:
- 接口可以扩展(
extends
),适用于面向对象编程。 - 类型别名更灵活,可以用于联合类型(
|
)等。
3. 可选属性和只读属性
(1)可选属性(?
)
使用 ?
使属性变为可选:
interface Product {
name: string;
price: number;
description?: string; // 可选属性
}
const p1: Product = { name: "Laptop", price: 1000 };
const p2: Product = { name: "Phone", price: 500, description: "A smartphone" };
(2)只读属性(readonly
)
readonly
使属性不可修改:
interface Config {
readonly apiKey: string;
}
const config: Config = { apiKey: "123456" };
// config.apiKey = "newKey"; // ❌ 报错:只读属性不能修改
4. 索引签名
当对象的属性名不确定时,可以使用索引签名:
interface User {
[key: string]: string; // 允许任意字符串作为属性名
}
const user: User = {
name: "Alice",
email: "alice@example.com",
address: "USA"
};
- 索引签名的限制: 所有属性值必须是
string
类型,否则会报错。
5. 对象的方法
对象可以定义方法:
interface MathOperation {
add(a: number, b: number): number;
}
const calculator: MathOperation = {
add: (x, y) => x + y
};
console.log(calculator.add(2, 3)); // 输出: 5
6. 对象的嵌套与组合
对象可以嵌套其他对象:
interface Address {
city: string;
zip: number;
}
interface Employee {
name: string;
address: Address;
}
const emp: Employee = {
name: "Alice",
address: { city: "New York", zip: 10001 }
};
7. 对象的扩展(继承 & 交叉类型)
(1)接口继承
interface Person {
name: string;
}
interface Employee extends Person {
jobTitle: string;
}
const worker: Employee = {
name: "John",
jobTitle: "Engineer"
};
(2)交叉类型(&
)
type Person = { name: string };
type Employee = { jobTitle: string };
type Worker = Person & Employee;
const worker: Worker = { name: "John", jobTitle: "Engineer" };
8. 对象的类型断言
类型断言用于强制指定对象的类型:
let data: any = { name: "Alice", age: 25 };
let user = data as { name: string; age: number };
console.log(user.name); // ✅
9. 对象的深拷贝与浅拷贝
(1)浅拷贝
const obj1 = { name: "Alice", age: 25 };
const obj2 = { ...obj1 };
obj2.age = 30;
console.log(obj1.age); // 25
console.log(obj2.age); // 30
(2)深拷贝
const deepClone = JSON.parse(JSON.stringify(obj1));
注意: JSON.parse(JSON.stringify())
不能复制方法,需要使用 lodash.cloneDeep()
等库。
10. 最佳实践
✅ 使用 interface
代替 type
,除非需要联合类型。
✅ 使用 readonly
限制对象的不可变性。
✅ 使用 ?
避免 undefined
赋值错误。
✅ 使用 extends
或 &
复用对象类型。
✅ 避免 any
,尽可能使用精确的类型。
11. 参考资料
- TypeScript 官方文档:Object Types
- MDN 文档:JavaScript Object
- TypeScript 深入指南:TypeScript Deep Dive
TypeScript 的对象系统强大而灵活,合理使用类型注解、接口、可选属性、索引签名等特性,可以大幅提升代码的可读性、可维护性和安全性。
发表回复