(这个例子由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方法。
请告诉我,
答案 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');
}
}
}