给定以下代码:
class Service {
actions: Record<string, Function>;
}
class ServiceRunner<S extends typeof Service> {
#service: Service
constructor(ServiceClass: S) {
this.#service = new ServiceClass();
for (const [actionName, actionFn] of Object.entries(this.#service.actions)) {
this[actionName] = (...args: any[]) => actionFn(...args);
}
}
}
class Foo extends Service {
constructor() {
super();
console.log("constructor of Foo")
}
actions: {
action1: () => {};
action2: (id: string) => {};
};
anotherMethodThatIsNotAnAction() {}
}
const runner = new ServiceRunner(Foo)
runner.action1(); // My goal would be to have completion and typing on "action1" here
runner.action2("ok") // the same
正如你所看到的,我在ServiceRunner
中动态地构建了一些函数,这些函数直接Map到给定的内部Service
函数,它工作正常(javascript代码运行正确),但是我没有任何线索来输入这些函数,以使它们等价于Foo
服务(或Service
的任何给定后代)中定义的函数。
我甚至不知道这是否可能。
1条答案
按热度按时间q5iwbnjs1#
一个类可以有一个索引签名,但是它不能有一个没有声明的静态类型成员。
如果
ServiceRunner
有其他不是来自服务类的成员,我会提醒您不要使用这种方法,因为可能会发生名称冲突。但是,如果您创建一个单独的构造函数签名来为返回的示例创建正确的类型,您可以在TS中实现这一点:
Playground链接
如果在
ServiceRunner
中没有任何额外的成员,您还可以将其简化为:Playground链接