在 TypeScript 中,对象(Object)是数据结构的核心概念之一。对象可以包含属性方法,并且可以使用类型注解、接口、类型别名等方式进行定义和约束,从而提高代码的可读性、可维护性和类型安全性。


目录

  1. 什么是对象?
  2. 对象类型的定义方式
    • 使用类型推断
    • 使用类型别名
    • 使用接口(interface
  3. 可选属性和只读属性
  4. 索引签名
  5. 对象的方法
  6. 对象的嵌套与组合
  7. 对象的扩展(继承 & 交叉类型)
  8. 对象的类型断言
  9. 对象的深拷贝与浅拷贝
  10. 最佳实践
  11. 参考资料

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 的对象系统强大而灵活,合理使用类型注解、接口、可选属性、索引签名等特性,可以大幅提升代码的可读性、可维护性和安全性。