TypeScript泛型Handler类适配问题:支持含函数的混合接口
调整TypeScript Handler类的泛型约束
问题背景
原Handler类的泛型约束要求接口所有属性必须是函数,导致ShouldWork这类混合属性(含函数+非函数)的接口无法实例化;同时send方法会错误提示非函数属性,调用时无法正确拦截非法参数。需要实现:
- 允许至少含一个函数属性的接口作为泛型参数
send方法仅提示并接受函数类型的属性名及对应函数参数
修正后的代码
interface Works { call(): void; } interface DoesntWork { value: number; } interface ShouldWork { value: number; call(): void; } // 泛型约束:T为对象且至少包含一个函数属性 class Handler<T extends object & (keyof { [K in keyof T as T[K] extends () => any ? K : never]: any } extends never ? never : T)> { // 仅允许传入T中属性为函数的键 public send<P extends keyof T as T[P] extends () => any ? P : never>( methodName: P, payload: T[P], ) { // 业务逻辑实现 } } const handlerA = new Handler<Works>(); // ✅ 正常实例化 const handlerB = new Handler<DoesntWork>(); // ❌ 报错(无函数属性,符合预期) const handlerC = new Handler<ShouldWork>(); // ✅ 正常实例化(含call函数) handlerA.send('call', () => null); // ✅ 合法调用 handlerB.send('value', 23); // ❌ 报错(handlerB无法实例化,符合预期) handlerC.send('call', () => null); // ✅ 合法调用 handlerC.send('value', 42); // ❌ 报错(value不是函数属性,无自动提示)
核心逻辑说明
- 泛型约束:通过
keyof { [K in keyof T as T[K] extends () => any ? K : never]: any } extends never ? never : T判断T是否存在函数属性,不存在则约束不通过,确保Handler只接受含至少一个函数属性的类型。 - send方法参数筛选:利用
as关键字过滤出T中属性为函数的键,使得methodName仅能选择合法的函数属性,同时自动提示也只会显示这些属性。
内容的提问来源于stack exchange,提问作者Kleywalker
相关产品推荐
相关产品推荐

