Typescript装饰器和泛型

njthzxwz  于 2023-05-30  发布在  TypeScript
关注(0)|答案(1)|浏览(125)

我对打字还是个新手。我尝试定义一个装饰器,它将向类添加一些元数据。但我得到了一些编译器错误,我没有成功地解决。
下面是我的代码:

import "reflect-metadata";

function DomainEvent<T extends object>(eventName: string) {
    return function <T extends object> (target: T): T {
        Reflect.defineMetadata('custom:annotation:DomainEvent', eventName, target as Object)

        return class extends target {
            constructor(...args: any[]) {
                super(...args);
            }
        } as T
    }
}

@DomainEvent('articles/created')
class ArticleCreated {
    id: string

    constructor(id: string) {
        this.id = id;
    }
}

const event = new ArticleCreated('test'))
// returns the event name.
console.log(Reflect.getMetadata('custom:annotation:DomainEvent', ArticleCreated))

错误:

[0] src/custom/domain-event.ts(5,66): error TS2345: Argument of type 'T' is not assignable to parameter of type 'Object'.
[0] src/custom/domain-event.ts(7,30): error TS2507: Type 'T' is not a constructor function type.

请帮助我解决这些错误。

7hiiyaii

7hiiyaii1#

您遇到的错误与泛型的使用和装饰器函数的返回类型有关。要解决这些错误,您可以尝试以下操作:

import "reflect-metadata";

function DomainEvent(eventName: string) {
    return function <T extends { new (...args: any[]): {} }>(target: T): T {
        Reflect.defineMetadata('custom:annotation:DomainEvent', eventName, target.prototype);

        return class extends target {
            constructor(...args: any[]) {
                super(...args);
            }
        };
    };
}

@DomainEvent('articles/created')
class ArticleCreated {
    id: string;

    constructor(id: string) {
        this.id = id;
    }
}

应用这些更改后,应解决错误。

相关问题