You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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不是函数属性,无自动提示)

核心逻辑说明

  1. 泛型约束:通过keyof { [K in keyof T as T[K] extends () => any ? K : never]: any } extends never ? never : T判断T是否存在函数属性,不存在则约束不通过,确保Handler只接受含至少一个函数属性的类型。
  2. send方法参数筛选:利用as关键字过滤出T中属性为函数的键,使得methodName仅能选择合法的函数属性,同时自动提示也只会显示这些属性。

内容的提问来源于stack exchange,提问作者Kleywalker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 02:25:23