主要区别
- 定义方式
- 接口(interface):使用
interface
关键字定义,例如:
interface User {
name: string;
age: number;
}
- 类型别名(type alias):使用
type
关键字定义,例如:
type UserType = {
name: string;
age: number;
};
- 扩展方式
- 接口(interface):可以通过
extends
关键字实现扩展。例如:
interface Admin extends User {
role: string;
}
- 类型别名(type alias):对于对象类型的扩展可以使用交叉类型(
&
)来实现。例如:
type AdminType = UserType & {
role: string;
};
- 适用类型
- 接口(interface):主要用于定义对象类型,并且在定义函数类型时,接口有独特的语法。例如:
interface AddFn {
(a: number, b: number): number;
}
- 类型别名(type alias):可以用于定义任何类型,包括联合类型、元组类型等。例如:
type StringOrNumber = string | number;
type UserInfo = [string, number];
- 重复定义
- 接口(interface):允许重复定义,会自动合并。例如:
interface User {
name: string;
}
interface User {
age: number;
}
// User接口最终包含name和age属性
- 类型别名(type alias):不允许重复定义,重复定义会报错。
模块化场景下各自适合的应用场景
- 接口(interface)
- 对象类型定义与扩展:当你需要定义一个对象类型,并可能在其他模块中对其进行扩展时,接口很合适。例如,在一个用户管理模块中,定义基本用户接口
User
,然后在管理员模块中通过扩展User
接口来定义Admin
接口。
// user.ts
export interface User {
name: string;
age: number;
}
// admin.ts
import { User } from './user';
export interface Admin extends User {
role: string;
}
- 函数类型定义:在定义函数类型时,接口的语法更清晰。例如,在一个数学运算模块中定义加法函数类型。
// math.ts
export interface AddFn {
(a: number, b: number): number;
}
export const add: AddFn = (a, b) => a + b;
- 类型别名(type alias)
- 联合类型和元组类型:当需要定义联合类型或元组类型时,类型别名更方便。例如,在一个数据处理模块中,可能接收字符串或数字类型的数据。
// data.ts
export type StringOrNumber = string | number;
export const processData = (data: StringOrNumber) => {
if (typeof data ==='string') {
return data.length;
} else {
return data.toFixed(2);
}
};
- 复杂类型组合:当需要将多个类型组合成一个新类型时,交叉类型结合类型别名很有用。例如,在一个具有多种权限的用户模块中。
// permission.ts
export type BasicPermission = {
read: boolean;
};
export type AdvancedPermission = {
write: boolean;
};
export type UserPermission = BasicPermission & AdvancedPermission;