知了常识站
白蓝主题五 · 清爽阅读
首页  > 电脑基础

TypeScript交叉类型:让类型组合更灵活

TypeScript交叉型:让类型组合更灵活

在写前端项目的时候,经常会遇到这样一种情况:一个对象既要具备用户信息,又要包含操作权限。比如你正在做一个后台管理系统,用户登录后,页面要显示他的基本信息,同时还要判断他有没有删除数据的权限。这时候如果用 TypeScript,该怎么定义这种“既是A又是B”的类型?答案就是——交叉类型。

交叉类型(Intersection Type)允许你把多个类型合并成一个,新类型拥有所有组成部分的特性。它的符号是 &,读作“和”,意思是“这个值必须同时满足这些类型”。

怎么用交叉类型?

举个例子。假设你有两个接口,一个描述用户的基本信息,另一个描述角色权限:

interface User {
name: string;
age: number;
}

interface AdminRole {
hasDeletePermission: boolean;
role: string;
}

现在你要定义一个管理员用户,他既有用户信息,又有管理权限。这时候就可以用交叉类型:

type AdminUser = User & AdminRole;

这样一来,AdminUser 就必须同时包含 nameagehasDeletePermissionrole 这四个字段。

实际使用时,就像这样:

const admin: AdminUser = {
name: "张三",
age: 30,
hasDeletePermission: true,
role: "admin"
};

如果漏了任何一个字段,TypeScript 编译器就会报错,帮你提前发现问题。

交叉类型还能处理函数和联合类型

不止对象可以交叉,函数也能用。比如你有两个函数类型,一个返回字符串,一个返回数字:

type StringFn = () => string;
type NumberFn = () => number;
type CombinedFn = StringFn & NumberFn;

虽然这个例子看起来有点奇怪——一个函数不可能同时只返回字符串又只返回数字——但在一些高级类型编程中,这种写法会出现在重载或泛型场景里,帮助类型系统更精确地推导。

另外,交叉类型和联合类型(|)经常一起出现。比如你有一个配置对象,某些字段可能是多种类型之一,但整体结构又要合并:

interface Logger {
log: (msg: string) => void;
}

interface Saver {
save: (data: string | number) => boolean;
}

type LoggerSaver = Logger & Saver;

这个 LoggerSaver 类型就既能打印日志,又能保存数据,适合用在需要同时记录和存储的模块中。

在日常开发中,交叉类型最常出现在封装组件或设计工具函数时。比如你写了一个 React 组件,既想接收通用的 props,又想额外加一些特定功能的配置,用交叉类型就很自然。

它不像继承那样有父子关系,而是平等地“拼接”多个类型,逻辑更清晰,也更容易维护。

掌握交叉类型,能让你在 TypeScript 中更自由地组合类型,写出既安全又灵活的代码。下次当你发现一个对象“又是这个,又是那个”的时候,别忘了试试 & 操作符。