【问题标题】:Extends common class and implement interface扩展通用类和实现接口
【发布时间】:2016-03-08 03:43:34
【问题描述】:

(这个例子是由 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方法。

请给我建议,

【问题讨论】:

  • 请参阅我对class C 等案例的回答的更新

标签: oop typescript


【解决方案1】:

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

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

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

类型保护:https://basarat.gitbooks.io/typescript/content/docs/types/typeGuard.html

更新

根据要求,如果确实想测试接口,则需要创建一个用户定义的类型保护(文档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');    
        }
    }
}

【讨论】:

  • 你不应该检查 IMyInterface 而不是 ClassB 吗?
  • 接口在运行时不存在,因此不能用于运行时检查
  • 如果确实需要检查接口契约,可以创建自定义类型保护
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-07
  • 2016-04-28
  • 2011-09-16
相关资源
最近更新 更多