TypeScript类泛型实现:如何为每个任务推断回调返回类型
实现带回调返回类型推断的TaskManager类
完全可以实现,核心是通过泛型映射类型追踪每个任务ID对应的回调返回类型,结合TypeScript的自动类型推断能力即可达成需求。以下是完整的实现方案:
核心实现代码
// 定义任务结构:taskId为字面量类型,callback为任意返回值的函数 type Task<TId extends string, TReturn> = { taskId: TId; callback: () => TReturn; }; // TaskManager类的泛型TTaskMap用于存储任务ID到返回类型的映射 class TaskManager<TTaskMap extends Record<string, any> = {}> { private tasks: { [K in keyof TTaskMap]: () => TTaskMap[K]; } = {} as any; // 注册任务:通过泛型参数自动推断当前任务的ID和返回类型,并扩展映射表 register<TId extends string, TReturn>(task: Task<TId, TReturn>): TaskManager<TTaskMap & Record<TId, TReturn>> { this.tasks[task.taskId] = task.callback; return this as any; } // 执行任务:根据传入的taskId自动推断对应的返回类型 execute<TId extends keyof TTaskMap>(taskId: TId): TTaskMap[TId] { return this.tasks[taskId](); } }
使用示例
const manager = new TaskManager() .register({ taskId: 'fetchUser', callback: () => ({ name: 'Alice', age: 30 }) }) .register({ taskId: 'calcTotal', callback: () => 100 + 200 }); // 自动推断返回类型:{ name: string; age: number } const user = manager.execute('fetchUser'); // 自动推断返回类型:number const total = manager.execute('calcTotal'); // TS会直接报错:不存在该taskId manager.execute('invalidTask');
关键说明
- 泛型
TTaskMap作为任务ID到返回类型的动态映射表,每次调用register时,会通过TTaskMap & Record<TId, TReturn>扩展映射表,实现类型的累积更新。 execute方法通过TId extends keyof TTaskMap约束任务ID的合法性,同时直接返回TTaskMap[TId],让TypeScript自动匹配对应任务的回调返回类型。- 初始化时
TTaskMap默认是空对象,随着任务注册逐步扩展类型信息,既保留了taskId的字面量提示,又能精准推断每个任务的返回类型。
内容的提问来源于stack exchange,提问作者Flo Ragossnig
相关产品推荐
相关产品推荐

