据我所知,装饰器不会改变类型。无论如何,我知道class decorators don't。您可能可以创建自己的函数,该函数采用类构造函数并返回具有修改后的原型方法的新类构造函数,并手动对其进行注释,但您不会为此使用装饰符表示法。装饰器仍然是函数调用的语法糖,因此,如果前者对您不起作用,则后者应该更灵活。
这是一种可能性:
type Asyncify<C extends new (...args: any) => any,K extends keyof InstanceType<C>> = new (...args: ConstructorParameters<C>) => {
[P in keyof InstanceType<C>]: P extends K ?
InstanceType<C>[K] extends (...args: infer A) => infer R ?
(...args: A) => Promise<R> : InstanceType<C>[K]
: InstanceType<C>[K]
};
function makeMethodAsync<
C extends new (...args: any) => any,K extends keyof InstanceType<C>
>(ctor: C,methodName: K): Asyncify<C,K> {
const c = class extends (ctor as any) { };
c.prototype[methodName as any] = async function (...args: any) {
return ctor.prototype[methodName].apply(this,args);
}
return c as any;
}
该实现使用大量的any
类型断言来使编译器静音。基本上,类型Asyncify<C,K>
接受构造函数类型C
和实例属性名称K
(应为方法名称;我不检查),然后求值为另一种构造类型其实例已为该方法Promise
返回一个K
,而其他属性则保持不变。该实现对其创建的新子类的原型执行类似的操作。 (我试图谨慎处理this
上下文;我认为您的装饰器可能会对类的实例访问其方法访问属性或其他方法的事情做坏事。)
让我们看看它是否有效:
const Example = makeMethodAsync(class Example {
prop = "hey";
syncDoTrue() {
console.log(this.prop)
return true;
}
asyncDoTrue() {
console.log(this.prop)
return true;
}
},"asyncDoTrue");
const e = new Example();
const b = e.syncDoTrue(); // hey
console.log(b); // true
const r = e.asyncDoTrue(); // hey
console.log(r); // Promise { <state>: "fulfilled",<value>: true }
我想对我很好。希望能有所帮助;祝你好运!
Link to code
本文链接:https://www.f2er.com/3169805.html