2016-11-30 97 views
0

我正在创建一个基类(这里称为顶部),我想用它为它的所有子元素创建一个蓝图。我通过在基础上创建抽象函数来做到这一点,以便孩子们必须执行该操作才能生效。下面是一个例子抽象方法的实现不需要相同的签名

interface ITopData { } 

abstract class top{ 

    constructor() { } 

    abstract test<T extends ITopData>(data: T): void; 

} 

interface IBottomData extends ITopData { } 

class bottom extends top { 

    constructor() { super() } 

    test<IBottomData>(data) { return } 

} 

但是,这是所需的代码时,我这样写

class bad extends top { 

    constructor() { super() } 

    test(data: string) { return } 
    //these implementations also dont cause any complaints 
    //test<T extends string>(data) { return } 
    //test() { return } 

} 

我要什么类是打字稿抱怨级“坏”犯规适当扩大级“顶”。当我写出来,虽然我没有从我的intellisense或我的transpiler投诉。

编辑:如果一个子类没有任何函数的实现,我会得到错误,但是在使用上面显示的任何实现时会出错。

回答

2

有一点要记住的是,string匹配interface ITopData {} - 由于接口没有属性,任何对象类型都会匹配它。

虽然TypeScript 2.0不强制基于泛型参数的类型,但如果直接指定参数的类型,则会出现编译器错误。方法参数的语义也保持不变。

interface ITopData { 
    // the interface must have at least one mandatory property, 
    // otherwise any object will match it 
    foo: number; 
} 

abstract class foo{ 
    constructor() { } 

    abstract test(data: ITopData): void; 
} 

interface IBottomData extends ITopData { } 

class bottom extends foo { 
    constructor() { super() } 

    test(data: IBottomData) { return } 
} 

class bad extends foo { 
    constructor() { super() } 

    test(data: string) { return; } 
} 

或者,指定类的泛型类型而不是方法。这样,只要类型不匹配,您也会收到编译器错误

interface ITopData { 
    // the interface must have at least one mandatory property, 
    // otherwise any object will match it 
    foo: number; 
} 

abstract class foo<T extends ITopData>{ 
    constructor() { } 

    abstract test(data: T): void; 
} 

interface IBottomData extends ITopData { } 

class bad1 extends foo<IBottomData> { 
    constructor() { super() } 

    test(data: string) { return } 
} 

class bad2 extends foo<string> { 
    constructor() { super() } 

    test(data: string) { return; } 
} 
+0

谢谢你,这是非常有帮助的。我试图按照标记界面模式,并将ITopData留空,但我现在看到如何与其他类型匹配会导致错误。谢谢你的建议 :) – Jake