如何为TypeScript多态函数添加类型注解?
TypeScript多态函数类型注解方案
问题背景
我定义了一组带有共同type字段的联合类型:
type T1 = { type: 't1', someKey: number }; type T2 = { type: 't2', anotherKey: string }; type T3 = { type: 't3', andAnotherKey: boolean }; type T = T1 | T2 | T3;
同时维护了一个函数映射,键对应类型的type字段值,值是接收对应类型参数的函数:
const TYPE_FN_MAP = { t1: (argT1: T1) => argT1.someKey, t2: (argT2: T2) => argT2.anotherKey, t3: (argT3: T3) => argT3.andAnotherKey, } as const
需要给下面的多态函数添加类型注解,满足两个核心需求:
- 新增类型时,只需扩展
TYPE_FN_MAP添加对应函数,polymorphicFn无需修改 - 若新类型遗漏
type字段,TypeScript要在polymorphicFn处报错
const polymorphicFn = (argT) => TYPE_FN_MAP[argT.type](argT);
解决方案
通过提取TYPE_FN_MAP的类型动态推导参数与返回值类型,同时确保参数合法性:
// 提取TYPE_FN_MAP的所有合法type键 type ValidTypeKeys = keyof typeof TYPE_FN_MAP; // 提取所有映射函数的参数类型,组成合法参数联合类型 type ValidArg = Parameters<typeof TYPE_FN_MAP[ValidTypeKeys]>[0]; // 为多态函数添加类型注解 const polymorphicFn = (argT: ValidArg): ReturnType<typeof TYPE_FN_MAP[ValidArg['type']]> => { return TYPE_FN_MAP[argT.type as ValidTypeKeys](argT); };
方案说明
- 自动同步类型范围:
ValidTypeKeys和ValidArg会自动跟随TYPE_FN_MAP的扩展更新,新增类型时无需修改函数注解。 - 严格类型约束:
ValidArg确保只有包含合法type字段且匹配映射函数参数的类型才能传入,遗漏type字段时会直接在函数调用处触发报错。 - 动态返回值推导:返回值类型通过
ValidArg['type']关联到对应映射函数的返回值,保持类型一致性。 - 类型断言消除歧义:
argT.type as ValidTypeKeys用于让TypeScript确认参数的type字段必然是TYPE_FN_MAP的合法键,避免不必要的类型报错。
验证示例
- 新增类型自动支持:添加
T4和对应映射函数后,polymorphicFn自动兼容新类型:type T4 = { type: 't4', newKey: symbol }; const TYPE_FN_MAP = { t1: (argT1: T1) => argT1.someKey, t2: (argT2: T2) => argT2.anotherKey, t3: (argT3: T3) => argT3.andAnotherKey, t4: (argT4: T4) => argT4.newKey, } as const; - 遗漏type字段触发报错:若新增类型缺少
type字段,TypeScript会在polymorphicFn的argT.type处提示属性不存在:type T5 = { missingTypeKey: number }; const TYPE_FN_MAP = { // ...原有内容 t5: (argT5: T5) => argT5.missingTypeKey, } as const;
内容的提问来源于stack exchange,提问作者Mikhail Unenov
相关产品推荐
相关产品推荐

