如何用枚举实现TypeScript函数的条件返回类型以减少冗余代码?
合并帖子查询函数的简洁实现方案
先明确基础类型与枚举
首先定义核心的类型与访问级别枚举,这是实现的基础:
// 访问级别枚举(用字符串枚举更直观) enum AccessLevel { Normal = 'normal', Protected = 'protected' } // 普通帖子类型(公开可见字段) type NormalPost = { id: number; title: string; content: string; comments: string[]; }; // 保护帖子类型(继承普通字段+敏感信息) type ProtectedPost = NormalPost & { sensitiveMetrics: { views: number; likes: number; internalNotes: string; }; };
两种简洁的实现方案
方案一:泛型+条件返回类型
直接利用TypeScript的条件类型,结合泛型绑定访问级别,让返回类型自动匹配传入的参数:
function getPost<T extends AccessLevel>( id: number, accessLevel: T ): T extends AccessLevel.Protected ? ProtectedPost : NormalPost { // 模拟数据库查询获取基础帖子数据 const basePost: NormalPost = { id, title: '示例帖子', content: '帖子正文内容', comments: ['用户评论1', '用户评论2'] }; // 根据访问级别返回对应类型 if (accessLevel === AccessLevel.Protected) { return { ...basePost, sensitiveMetrics: { views: 1200, likes: 68, internalNotes: '仅创建者可见的内部数据' } } as ProtectedPost; } return basePost as NormalPost; }
调用时TypeScript会自动推断返回类型:
const publicPost = getPost(1, AccessLevel.Normal); // publicPost 类型为 NormalPost,无法访问 sensitiveMetrics const creatorPost = getPost(1, AccessLevel.Protected); // creatorPost 类型为 ProtectedPost,可访问所有字段
方案二:函数重载(更直观)
如果不需要泛型的灵活性,函数重载的写法可读性更强,直接为不同访问级别参数指定对应返回类型:
// 重载签名:定义不同参数对应的返回类型 function getPost(id: number, accessLevel: AccessLevel.Normal): NormalPost; function getPost(id: number, accessLevel: AccessLevel.Protected): ProtectedPost; // 实现签名:统一处理业务逻辑 function getPost(id: number, accessLevel: AccessLevel): NormalPost | ProtectedPost { const basePost: NormalPost = { id, title: '示例帖子', content: '帖子正文内容', comments: ['用户评论1', '用户评论2'] }; if (accessLevel === AccessLevel.Protected) { return { ...basePost, sensitiveMetrics: { views: 1200, likes: 68, internalNotes: '仅创建者可见的内部数据' } }; } return basePost; }
这种方式调用时的类型推断效果和方案一完全一致,代码逻辑更直白。
关于你的构想
你提出的用枚举作为条件的思路完全正确,只需修正枚举的语法(TypeScript枚举定义不用=,而是enum AccessLevel { ... }),再结合上述两种方式,就能实现简洁的合并函数,彻底消除代码冗余。
内容的提问来源于stack exchange,提问作者Dmitry Filippov
相关产品推荐
相关产品推荐

