2017-04-17 38 views
0

我想为typescript中的类装饰器定义一个装饰器签名,用于已存在的JavaScript代码。比方说,我有一些已经定义的类Foo具有所需方法的类装饰器签名

class Foo { 
    someMethod() { 
    } 
} 

然后也有一些它需要输入类类的装饰方法,但它要求输入类有它的装饰之前定义的其它一些方法。

function decorate(someClass) { 
    // some properties and methods injection happens here 
} 

然后在我的打字稿的代码,我将创建一个类来装饰为:

class Bar extends Foo { 
    requiredMethod(): any { 
    return null; 
    } 
} 

那么对于定义我想:

interface WithRequiredMethod { 
    requiredMethod(): any; 
} 

declare function decorate<C extends Foo>(input: C & WithRequiredMethod): C; 

然后调用它为:

const DocoratedBar = decorate(Bar); 

不幸的是typescript doesn'即使定义了requiredMethod,也不会将Bar识别为有效输入。有什么方法可以定义decorate签名来验证输入类中是否存在requiredMethod

回答

0

你几乎拥有它。但你需要写这个

interface WithRequiredMethod { 
    // tslint:disable-next-line:no-any 
    requiredMethod(): any; 
} 

declare function decorate<C extends new() => Foo & WithRequiredMethod>(target: C): C; 

原因是装饰目标的一个类。一个类实际上只是一个构造函数。所以装饰的对象实际上是Foo & WithRequiredMethod类型的对象的构造函数。

例如,如果我们只是想限制我们的装饰靶向Foo或它的一个子类,我们会写

declare function decorate<T extends typeof Foo>(target: T): T; 

有趣的是,最初收到的错误,指出class Bar没有实现WithRequiredMethod,这是确实如此,但不是我们想说的。但是,说出来和说出时我们可以利用装饰器强制实现静态属性和实例属性。

考虑:

declare function decorate< 
    C extends WithRequiredMethod & (new() => Foo & WithRequiredMethod) 
>(target: C): C; 

现在我们应用此class Bar,再次收到requiredMethod缺少错误。但是,我们可以通过添加静态requiredMethod方法Bar满足要求:

@decorate class Bar extends Foo { 
    // required by `decorate` 
    static requiredMethod() { 
    // tslint:disable-next-line:no-null-keyword 
    return null; 
    } 

    // also required by `decorate` 
    requiredMethod() { 
    // tslint:disable-next-line:no-null-keyword 
    return null; 
    } 
} 
+0

谢谢,这是我忽视。 –