扩展公共类和实现接口

时间:2016-03-08 03:43:34

标签: oop typescript

(这个例子由Typescript编写,但不仅仅是在Typescript案例中)

class IMyInterface {
    doC:(any) => any;
}

class Common {
    commonProperty:any;

    doA() {
    }

    doB() {
    }
}

class ClassA extends Common {}
class ClassB extends Common implements IMyInterface {
    doC(test:any) {
        return true;
    }   
}


class Factory {
    myClass: Common;

    doSomething() {
        // Property 'doC' does not exist on type 'Common'
        this.myClass.doC('test');
    }
}

A类和B类是扩展的Common类,因此在Factory类中可以将myClass类型定义为Common。

但是B类需要实现IMyInterface,而Common类并没有包含它。因此,Factory类抛出一个错误,即Common类上不存在接口方法。

解决这个问题的最佳解决方法是什么?是什么?

[编辑]

首先,@ basarat非常感谢你,但我还是有点好奇,

如果还有一些类实现了IMyInterface

,该怎么办?
class ClassC extends Common implements IMyInterface {
    doC(test:any) {
        return true;
    }   
}
class ClassD extends Common implements IMyInterface {
    doC(test:any) {
        return true;
    }   
}
class ClassE extends Common implements IMyInterface {
    doC(test:any) {
        return true;
    }   
}

在这种情况下,我可以认为,我可以在Common类中定义doC()方法。 但我也想让ClassB,C,D和E必须实现Doc方法。

请告诉我,

1 个答案:

答案 0 :(得分:1)

  

如何以及解决此问题的最佳方法

您基本上想说myClass通常只是Common,但在特殊情况下,可能ClassB。您可以使用联合类型+使用typeguard执行此操作:

class Factory {
    myClass: Common | ClassB;

    doSomething() {
        const myClass = this.myClass;
        if (myClass instanceof ClassB){
            // works!
            myClass.doC('test');    
        }
    }
}

更多

完整示例:

class IMyInterface {
    doC:(any) => any;
}

class Common {
    commonProperty:any;
    doA() {
    }
    doB() {
    }
}

class ClassA extends Common {}
class ClassB extends Common implements IMyInterface {
    doC(test:any) {
        return true;
    }   
}


class Factory {
    myClass: Common | ClassB;

    doSomething() {
        const myClass = this.myClass;
        if (myClass instanceof ClassB){
            // works!
            myClass.doC('test');    
        }
    }
}

文档

联盟类型:https://basarat.gitbooks.io/typescript/content/docs/types/type-system.html#union-type

键入Guard:https://basarat.gitbooks.io/typescript/content/docs/types/typeGuard.html

更新

根据要求,如果确实要测试接口,则需要创建用户定义的类型保护(docs https://basarat.gitbooks.io/typescript/content/docs/types/typeGuard.html#user-defined-type-guards)。示例:

function isMyInterface(foo:any): foo is IMyInterface {
    return typeof foo.doC === 'function';
}

class Factory {
    myClass: Common | IMyInterface;

    doSomething() {
        const myClass = this.myClass;
        if (isMyInterface(myClass)){
            // works!
            myClass.doC('test');    
        }
    }
}

完整的代码变为:

class IMyInterface {
    doC:(any) => any;
}

class Common {
    commonProperty:any;
    doA() {
    }
    doB() {
    }
}

class ClassA extends Common {}
class ClassB extends Common implements IMyInterface {
    doC(test:any) {
        return true;
    }   
}
class ClassC extends Common implements IMyInterface {
    doC(test:any) {
        return true;
    }   
}
class ClassD extends Common implements IMyInterface {
    doC(test:any) {
        return true;
    }   
}
class ClassE extends Common implements IMyInterface {
    doC(test:any) {
        return true;
    }   
}

function isMyInterface(foo:any): foo is IMyInterface {
    return typeof foo.doC === 'function';
}

class Factory {
    myClass: Common | IMyInterface;

    doSomething() {
        const myClass = this.myClass;
        if (isMyInterface(myClass)){
            // works!
            myClass.doC('test');    
        }
    }
}