TypeScript如何优雅处理业务场景下重复相似的类型定义?
TypeScript 重复相似接口优化方案
你可以通过TypeScript的内置工具类型、接口继承能力来消除重复的字段定义,核心思路是从公共基础类型派生出不同业务场景的子类型,完全不需要单独定义4个独立接口。
下面提供两种常用的优化方案,和你原有接口结构完全等价,不需要修改现有业务逻辑即可直接替换:
方案1:抽离公共基础字段(推荐,可维护性最高)
先抽离所有评论/回复共有的基础内容字段,后续所有相关类型都从基础字段扩展:
// 抽离所有评论、回复共有的基础内容字段 interface BaseCommentContent { author: string; body: string; } // 新建评论直接复用基础字段 export type NewComment = BaseCommentContent; // 存入状态的无回复评论,扩展基础字段增加独有属性 export interface CommentWithoutReplies extends BaseCommentContent { id: string; postedAt: number; replies_count: number; } // 服务端返回的完整评论,扩展无回复评论类型增加replies字段 export interface Comment extends CommentWithoutReplies { replies: Reply[]; } // 回复类型,扩展基础字段增加独有属性 export interface Reply extends BaseCommentContent { id: string; comment_id: string; postedAt: number; }
这种方案的优势是后续如果要调整基础字段(比如给body加长度限制、新增自定义表情字段),只需要修改BaseCommentContent一处即可全局生效,不需要同步修改多个接口。
方案2:基于内置工具类型派生(适合字段稳定的场景)
如果你的业务字段基本不会变动,可以直接用TS内置的Pick、Omit工具类从完整的服务端类型直接派生出其他类型:
// 先定义回复类型 export interface Reply { id: string comment_id: string, author: string, body: string, postedAt: number, } // 定义服务端返回的完整评论类型 export interface Comment { id: string, author: string, body: string, postedAt: number, replies_count: number, replies: Reply[] } // 剔除replies字段得到无回复评论类型 export type CommentWithoutReplies = Omit<Comment, 'replies'> // 提取author、body两个字段得到新建评论类型 export type NewComment = Pick<Comment, 'author' | 'body'>
这种方案代码更简洁,不需要单独维护基础字段类型。
内容的提问来源于stack exchange,提问作者SrdjaNo1
相关产品推荐
相关产品推荐

