首页 文章

实现接口的TypeScript装饰器声明

提问于
浏览
0

我尝试了几种不同的方法在TypeScript中声明一个装饰器函数,使装饰类实现一个接口 . 像这样的东西:

interface IValidatable {
    checkValidation: () => boolean;
}

function validated<T>(Class: {new():T}): {new():T & IValidatable} {
    Class.prototype.checkValidation = () => true;
    return Class as {new():T & IValidatable};
}

鉴于上述情况,我希望我能做到这样的事情:

@validated
class Foo {

}

let f = new Foo();
let isValid = f.checkValidation();

但最后一行被标记为错误(“Foo”类型上不存在“属性'checkValidation' . ”) .

以下内容确实起作用,因为它不会生成错误:

let ValidatedFoo = validated(Foo);
let vf = new ValidatedFoo();
let isValid2 = vf.checkValidation();

有没有办法制定装饰器声明,以便第一个用法示例不会产生错误?

1 回答

  • 1

    我不认为你可以修复它,以便装饰器改变编译器对 Foo 类的思考方式 .
    装饰器在运行时工作而不是编译时,因此当您实例化 Foo 时,编译器会看到 Foo .

    我可以想到以下三个选项:

    (1)投射实例:

    let f = new Foo() as Foo & IValidatable;
    let isValid = f.checkValidation();
    

    (2)将 class 投入交叉路口:

    interface FooConstructor {
        new (): Foo & IValidatable;
    }
    
    let f = new (Foo as FooConstructor)();
    let isValid = f.checkValidation();
    

    (3)使用工厂功能:

    function fooFactory(): Foo & IValidatable {
        return new Foo() as Foo & IValidatable;
    }
    
    let f = fooFactory();
    let isValid = f.checkValidation();
    

    code in playground

相关问题