TypeScript嵌套泛型实现:约束类型参数为Worker接口实现类
TypeScript 嵌套泛型约束实现方案
TypeScript 支持这类泛型约束需求,原示例中interface WorkerPool<W<U>>的写法属于TypeScript不支持的高阶类型形参语法,调整泛型定义、通过extends添加类型约束即可实现要求的校验规则。
核心实现代码
直接给WorkerPool接口的泛型参数添加上下文约束,要求传入的类型必须符合Worker接口结构即可,不需要声明额外的高阶类型参数:
interface Worker<T> { renderChunk: (projectUrl: string, from: number, to: number) => Promise<T>; } // 泛型W添加约束:必须是Worker的实现类型 interface WorkerPool<W extends Worker<unknown>> { addWorker(worker: W, address: number): void; getIdleWorker(): W | null; }
校验效果验证
合法场景(类型校验通过)
示例中的RenderWorker实现了Worker<string[]>,符合Worker<unknown>的结构约束,传入WorkerPool时不会触发类型错误:
class RenderWorker implements Worker<string[]> { async renderChunk(projectUrl: string, from: number, to: number): Promise<string[]> { return Promise.resolve(['Foo']) } } // 类型校验完全合法 class RenderWorkerPool implements WorkerPool<RenderWorker> { addWorker(worker: RenderWorker, address: number): void { // 业务实现逻辑 } getIdleWorker(): RenderWorker | null { // 业务实现逻辑 return null } }
非法场景(类型校验报错)
如果传入非Worker实现的类型(比如基础类型string),TypeScript会直接抛出类型错误,符合需求:
// 类型错误:string 不满足约束 Worker<unknown> class InvalidWorkerPool implements WorkerPool<string> {}
扩展场景
如果你需要在WorkerPool内部获取Worker对应的产出类型T,可以将T也声明为泛型参数,支持更精细的类型推导:
// 双泛型参数定义,支持在接口内部直接使用T类型 interface WorkerPool<T, W extends Worker<T> = Worker<T>> { addWorker(worker: W, address: number): void; getIdleWorker(): W | null; // 例:批量处理方法的返回值可以直接推导为T[] batchRender(projectUrl: string, ranges: Array<[number, number]>): Promise<T[]> }
说明:原写法中的
W<U>属于高阶类型形参语法,目前TypeScript原生不支持这种声明方式,所有泛型的子类型约束都通过extends关键字实现,用unknown作为Worker的泛型占位符即可匹配所有Worker实现类型,不会丢失类型校验能力。
内容的提问来源于stack exchange,提问作者Abouhassane Abdelhamid
相关产品推荐
相关产品推荐

