Typescript 使用方法修饰符更改函数返回类型

Typescript 使用方法修饰符更改函数返回类型,typescript,decorator,typescript-decorator,Typescript,Decorator,Typescript Decorator,下面我有一个返回布尔值的sync函数,我使用这个decorator@MakeAsync来更改函数。我很好奇在做了这个更改之后,如何更新函数的返回类型。我尝试使用Promise,但失败了 装饰程序是否可以覆盖方法的类型定义(参数和返回类型) function MakeAsync() { console.log("f(): evaluated"); return function (target, key: string, descriptor: PropertyDescriptor

下面我有一个返回布尔值的sync函数,我使用这个decorator
@MakeAsync
来更改函数。我很好奇在做了这个更改之后,如何更新函数的返回类型。我尝试使用
Promise
,但失败了

装饰程序是否可以覆盖方法的类型定义(参数和返回类型)

function MakeAsync() {
    console.log("f(): evaluated");
    return function (target, key: string, descriptor: PropertyDescriptor) {
        const original = descriptor.value;
        if (typeof original === 'function') {
            descriptor.value = async (...args): Promise<ReturnType<typeof original>> => {
                return original(...args)
            }
        }
        return descriptor;
    }
}

class Example {    
    @MakeAsync()
    doTrue (): Boolean {
        return true
    }
}

const e = new Example

console.log(e.doTrue())
函数MakeAsync(){
log(“f():已评估”);
返回函数(目标、键:字符串、描述符:PropertyDescriptor){
const original=descriptor.value;
如果(原始类型==='函数'){
descriptor.value=async(…args):Promise=>{
返回原始(…args)
}
}
返回描述符;
}
}
类示例{
@MakeAsync()
doTrue():布尔值{
返回真值
}
}
常数e=新示例
console.log(e.doTrue())

据我所知,装饰器不会变异类型。反正我知道。您可能可以创建自己的函数,该函数接受一个类构造函数并返回一个带有修改原型方法的新类构造函数,然后手动对其进行注释,但您不会为此使用装饰符号。无论如何,修饰符都是函数调用的语法糖,因此,如果前者不适用于您,那么后者应该更灵活

这里有一种可能性:

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;
}
我想对我来说很好。希望有帮助;祝你好运

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 }