别再堆 if-else 了!TypeScript 模式匹配让代码更优雅
日常开发中,if-else 嵌套或 switch-case 判断是处理多分支逻辑的常用方式。但随着业务迭代,分支条件会越来越复杂,代码嵌套层级不断加深,可读性和维护性大幅下降。尤其在 TypeScript 项目中,这种写法还会浪费类型系统的优势。其实借助 TS 的类型特性,用模式匹配重构多分支逻辑,能让代码更简洁、类型更安全。
一、传统写法的痛点
以处理不同类型的表单提交逻辑为例,传统 if-else 写法如下:
typescript
// 表单类型定义
type FormType = 'login' | 'register' | 'reset'
// 表单数据类型
interface LoginForm {
username: string
password: string
}
interface RegisterForm {
email: string
password: string
confirmPassword: string
}
interface ResetForm {
email: string
code: string
}
// 传统处理逻辑
function handleFormSubmit(type: FormType, data: LoginForm | RegisterForm | ResetForm) {
if (type === 'login') {
// 登录逻辑
console.log(data.username, data.password)
} else if (type === 'register') {
// 注册逻辑
console.log(data.email, data.password, data.confirmPassword)
} else if (type === 'reset') {
// 重置密码逻辑
console.log(data.email, data.code)
}
}
这种写法存在明显问题:
- 类型不安全,需手动判断类型,容易出现数据属性访问错误;
- 新增表单类型时,需修改 if-else 分支,违反开闭原则;
- 分支过多时,代码冗长,难以快速定位对应逻辑。
二、模式匹配的核心思路
模式匹配的核心是将 "条件判断" 转化为 "类型映射 + 函数分发",利用 TS 的类型推断自动关联条件与处理逻辑,实现类型安全与逻辑解耦。
核心步骤:
- 定义类型映射,关联条件类型与对应数据类型;
- 编写处理函数字典,key 为条件类型,value 为对应处理逻辑;
- 封装分发函数,根据输入类型自动匹配处理函数。
三、TypeScript 模式匹配实现
1. 定义类型映射与处理函数字典
typescript
// 类型映射:关联表单类型与数据类型
type FormMap = {
login: LoginForm
register: RegisterForm
reset: ResetForm
}
// 处理函数类型:与类型映射对应
type FormHandler = {
[K in keyof FormMap]: (data: FormMap[K]) => void
}
// 处理函数字典:实现各类型表单的处理逻辑
const formHandlers: FormHandler = {
login: (data) => {
console.log(data.username, data.password)
// 登录逻辑实现
},
register: (data) => {
console.log(data.email, data.password, data.confirmPassword)
// 注册逻辑实现
},
reset: (data) => {
console.log(data.email, data.code)
// 重置密码逻辑实现
}
}
2. 封装分发函数
typescript
// 分发函数:自动匹配类型与处理逻辑
function submitForm<K extends keyof FormMap>(type: K, data: FormMap[K]) {
const handler = formHandlers[type]
if (!handler) {
throw new Error(`未找到${type}类型的表单处理逻辑`)
}
handler(data)
}
3. 调用示例
php
// 登录表单提交
submitForm('login', { username: 'test', password: '123456' })
// 注册表单提交
submitForm('register', { email: 'test@xxx.com', password: '123456', confirmPassword: '123456' })
// 重置密码表单提交
submitForm('reset', { email: 'test@xxx.com', code: '666666' })
四、模式匹配的优势
- 类型安全:TS 会自动校验数据类型与表单类型是否匹配,避免属性访问错误;
- 逻辑解耦:处理逻辑按类型拆分到独立函数,代码结构清晰,便于维护;
- 扩展性强:新增表单类型时,只需在类型映射和处理函数字典中添加对应项,无需修改分发函数;
- 可读性高:通过类型映射可快速关联条件与处理逻辑,无需遍历 if-else 分支。
五、进阶用法:带返回值的模式匹配
若处理逻辑需要返回值,可扩展类型定义与处理函数:
typescript
// 扩展返回值类型映射
type FormResultMap = {
login: { success: boolean; token?: string }
register: { success: boolean; userId?: number }
reset: { success: boolean; message: string }
}
// 带返回值的处理函数类型
type FormResultHandler = {
[K in keyof FormMap]: (data: FormMap[K]) => FormResultMap[K]
}
// 带返回值的处理函数字典
const formResultHandlers: FormResultHandler = {
login: (data) => {
// 登录逻辑实现
return { success: true, token: 'xxx' }
},
register: (data) => {
// 注册逻辑实现
return { success: true, userId: 1001 }
},
reset: (data) => {
// 重置密码逻辑实现
return { success: true, message: '密码重置成功' }
}
}
// 带返回值的分发函数
function submitFormWithResult<K extends keyof FormMap>(type: K, data: FormMap[K]): FormResultMap[K] {
const handler = formResultHandlers[type]
if (!handler) {
throw new Error(`未找到${type}类型的表单处理逻辑`)
}
return handler(data)
}
六、总结
TypeScript 模式匹配通过 "类型映射 + 函数分发" 的方式,彻底摆脱了传统 if-else 和 switch-case 的弊端。它既利用了 TS 的类型系统保障代码安全,又实现了逻辑的解耦与扩展,让多分支逻辑代码更优雅、更易维护。
在处理状态管理、表单提交、接口响应解析等多分支场景时,不妨尝试用模式匹配重构代码,既能提升开发效率,又能让代码质量更上一层楼。