一、基本概念
在 TypeScript 中,对象类型可以通过字面量表示法来定义一个对象。字面量表示法可以定义一个对象的属性名和属性值,然后将其放在一对花括号中,以表示一个对象。
{
name: string,
age: number,
phone?: string
}
此处定义了一个对象类型,它包含三个属性:name、age 和 phone,其中 phone 属性是可选属性,表示该属性可以存在也可以不存在。
对象类型还可以使用接口(interface)或类型别名(type)来定义:
interface Person {
name: string,
age: number,
phone?: string
}
type PersonAgain {
name: string,
age: number,
phone?: string
}
这里以接口为例,定义了一个名为 Person 的接口,其属性与上面的字面量表示法一致。
二、属性修饰符
在对象类型中,属性可以具有以下修饰符:
readonly
:表示该属性只读(不可修改)public
:表示该属性是公共属性(默认值,可以在任何地方访问)private
:表示该属性是私有属性(只能在类内部访问)protected
:表示该属性是受保护属性(只能在基类或其子类内部访问)
示例代码如下:
interface Point {
readonly x: number,
readonly y: number,
z?: number
}
class PointThreeD implements Point {
readonly x: number;
readonly y: number;
readonly z: number;
constructor(x: number, y: number, z: number) {
this.x = x;
this.y = y;
this.z = z;
}
}
let p3d = new PointThreeD(1, 2, 3);
console.log(p3d.x); // 输出 1
p3d.x = 4; // 报错,属性 'x' 只读
在这个例子中,定义了一个名为 Point 的接口,它包含两个只读属性:x 和 y,以及一个可选属性 z。并且还定义了一个名为 PointThreeD 的类,该类对接口 Point 进行实现,并在构造函数中为所有属性赋值。p3d 为 PointThreeD 类型的一个实例,可以访问其属性 x、y 和 z(只有 PointThreeD 类型才有 z 属性)。
三、键名签名
在 TypeScript 中,对象类型还可以使用键名签名来定义一系列属性。键名签名包含两个部分:键名类型和键值类型。
interface Dict {
[key: string]: string;
}
let dict: Dict = {
name: 'Tom',
age: '18',
phone: '1234567890'
};
在这个例子中,定义了一个名为 Dict 的接口,它包含一个键名为 string 类型、键值为 string 类型的键名签名。dict 为 Dict 类型的一个实例,可以访问其所有键值。
四、交叉类型
交叉类型(Intersection Types)表示多个类型的交集。通过交叉类型,我们可以将多个对象类型合并成一个对象类型。
interface User {
name: string;
age: number;
}
interface UserInfo {
city: string;
occupation: string;
}
type UserAndInfo = User & UserInfo;
let user: UserAndInfo = {
name: 'Tom',
age: 18,
city: 'Beijing',
occupation: 'Engineer'
}
在这个例子中,定义了两个接口 User 和 UserInfo,它们分别定义了用户和用户信息的属性。接着定义了一个名为 UserAndInfo 的类型别名,它是 User 类型和 UserInfo 类型的交集。最后定义了一个 user 对象为 UserAndInfo 类型,可以访问其属性 name、age、city 和 occupation。
五、联合类型
联合类型(Union Types)表示多个类型的并集。通过联合类型,我们可以将多种不同对象类型合并成一个对象类型。
interface Cat {
type: 'cat',
name: string,
sound: string
}
interface Dog {
type: 'dog',
name: string,
sound: string
}
type CatAndDog = Cat | Dog;
function playSound(animal: CatAndDog) {
console.log(animal.sound);
}
let cat = { type: 'cat', name: 'Tom', sound: 'Meow' };
let dog = { type: 'dog', name: 'Jerry', sound: 'Bark' };
playSound(cat); // 输出 'Meow'
playSound(dog); // 输出 'Bark'
在这个例子中,定义了两个接口 Cat 和 Dog,它们分别定义了猫和狗的属性。接着定义了一个名为 CatAndDog 的联合类型,它是 Cat 类型和 Dog 类型的并集。最后定义了一个 playSound 函数,该函数的参数 animal 可以是 CatAndDog 类型,然后在函数体内输出 animal 的声音。
六、索引类型
索引类型(Index Types)允许我们动态地访问和操作对象的属性。在 TypeScript 中,索引类型有两种:字符串索引和数字索引。
字符串索引允许我们使用字符串来访问对象的属性:
interface Dict {
[key: string]: string;
}
let dict: Dict = {};
dict['name'] = 'Tom';
dict['age'] = '18';
在这个例子中,定义了一个名为 Dict 的接口,它包含一个字符串索引,其键类型为 string,值类型为 string。然后定义了一个 dict 对象为 Dict 类型,可以动态地向 dict 对象中添加属性和属性值。
数字索引允许我们使用数字来访问对象的属性:
interface NumberArray {
[index: number]: number;
}
let arr: NumberArray = [1, 2, 3];
let num: number = arr[0];
在这个例子中,定义了一个名为 NumberArray 的接口,它包含一个数字索引,其键类型为 number,值类型为 number。然后定义了一个 arr 对象为 NumberArray 类型,可以动态地添加数字类型的属性和属性值。
七、总结
在 TypeScript 中,对象类型是一个非常重要的概念。通过对象类型的深入了解,我们可以更好地理解 TypeScript 语法,从而提高我们的编程效率。