自定义类型(type、interface)
在 TypeScript 中,自定义类型是通过类型别名 (type) 和接口 (interface) 来实现的。它们允许你创建复杂的数据结构,并为这些结构提供明确的类型定义。下面详细介绍如何使用这两种方式来创建和使用自定义类型。
类型别名(Type Aliases)
类型别名让你可以给任何类型一个名字,包括原始类型、联合类型、交叉类型、元组等。它特别适合用于简化复杂的类型表达式或为常用模式命名。
定义简单类型别名
typescript
type ID = number | string;这里,ID 是一个联合类型,表示它可以是数字或字符串。
定义复杂类型
你可以组合多个类型来创建更复杂的类型:
typescript
type Point = {
x: number;
y: number;
};
type PartialPointX = { x?: number };
type PartialPointY = { y?: number };
type PartialPoint = PartialPointX | PartialPointY;使用泛型创建可重用的类型别名
typescript
type Container<T> = { value: T };这定义了一个 Container 类型,它可以包含任意类型的值。
联合类型与交叉类型
联合类型:表示一个值可以是几种类型中的一种。
typescripttype ID = number | string;交叉类型:将多个类型的属性合并成一个新的类型。
typescripttype Admin = { role: "admin" }; type User = { name: string; id: number }; type AdminUser = Admin & User;
接口(Interfaces)
接口主要用于定义对象的形状,也可以扩展其他接口以添加更多属性或方法。接口在某些情况下比类型别名更灵活,例如它们支持声明合并。
定义简单的接口
typescript
interface LabelledValue {
label: string;
}扩展接口
接口可以从其他接口继承,从而扩展现有的定义:
typescript
interface Shape {
color: string;
}
interface Square extends Shape {
sideLength: number;
}接口中的可选属性
接口中的属性可以被标记为可选:
typescript
interface SquareConfig {
color?: string;
width?: number;
}只读属性
使用 readonly 关键字可以定义只读属性:
typescript
interface Point {
readonly x: number;
readonly y: number;
}函数类型接口
接口还可以用来定义函数的类型签名:
typescript
interface SearchFunc {
(source: string, subString: string): boolean;
}可索引类型接口
对于那些可以通过索引访问的数据结构(如数组或映射),你可以定义索引签名:
typescript
interface StringArray {
[index: number]: string;
}混合类型接口
有时你可能想要一个接口既有数据属性又有函数调用的能力。这称为混合类型接口:
typescript
interface Counter {
(start: number): string;
interval: number;
reset(): void;
}类型别名 vs. 接口
类型别名:
- 更加灵活,可以用于原始类型、联合类型、交叉类型等。
- 不支持声明合并。
- 适用于创建复杂类型和泛型容器类型。
接口:
- 主要用于定义对象的形状。
- 支持声明合并,即如果两个同名接口存在于同一个作用域内,它们会自动合并。
- 更适合描述对象的结构,尤其是当需要扩展现有定义时。
总结
通过类型别名和接口,TypeScript 提供了强大的工具来创建自定义类型,确保代码的类型安全性和可维护性。根据你的需求选择合适的方式来定义类型,可以使代码更加清晰和易于理解。