如何精简返回函数的函数TypeScript类型定义消除重复
问题背景
开启强制所有函数显式指定返回类型的ESLint规则后,编写返回函数的React Hook时,很容易出现外层Hook返回类型、内层返回函数的参数/返回类型重复书写的冗余代码,典型示例如下:
const useSubmitForm = (): (( form: FormProps, submissions: (string | MultipleChoiceOption[])[], user: string ) => FormEventHandler) => { const notify = useNotification(); return ( form: FormProps, submissions: (string | MultipleChoiceOption[])[], user: string ): FormEventHandler => (e) => { // 业务逻辑 }; };
这类重复定义违反DRY原则,后续修改参数时需要同步改动多处,很容易因为漏改出现类型不一致问题。
优化方案
最通用、无额外运行时成本的方案是提前抽离重复的函数类型为公共类型别名,两处定义统一引用该别名即可,完全符合类型安全要求和ESLint规则:
- 首先在模块作用域定义抽离的公共类型:
// 抽离重复的表单提交处理函数类型 type SubmitFormHandler = ( form: FormProps, submissions: (string | MultipleChoiceOption[])[], user: string ) => FormEventHandler;
- 重构Hook代码,外层返回类型直接引用该别名,内层函数依托TS的上下文类型推导,可以省略重复的参数类型书写,仅保留规则要求显式声明的返回类型即可:
const useSubmitForm = (): SubmitFormHandler => { const notify = useNotification(); // TS会自动根据外层返回类型推导参数类型,无需重复书写 return (form, submissions, user): FormEventHandler => (e) => { // 编写业务逻辑即可 }; };
补充说明
- 如果你的ESLint配置同时强制要求所有函数参数必须显式标注类型,可以配合TS内置的
Parameters工具类型复用抽离的类型,不需要重复书写长联合类型定义:
const useSubmitForm = (): SubmitFormHandler => { const notify = useNotification(); return ( form: Parameters<SubmitFormHandler>[0], submissions: Parameters<SubmitFormHandler>[1], user: Parameters<SubmitFormHandler>[2] ): FormEventHandler => (e) => { // 业务逻辑 }; };
- 不要为了精简代码直接用
any、类型断言绕过类型检查,也不建议随意关闭ESLint的显式返回类型规则。抽离类型别名的方式既满足规范要求,也能做到类型定义单点维护,后续调整入参或返回值时只需要修改SubmitFormHandler一处即可,从根源上避免多出处同步修改的问题。
内容的提问来源于stack exchange,提问作者gxk28
相关产品推荐
相关产品推荐

