2016-03-08 6 views
0

(этот пример, написанный машинописи, но не только в машинописи случае)Расширяет общий класс и реализовать интерфейс

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'); 
    } 
} 

класса А и В вытянуты общий класс, так что в Factory класс может определить MyCLASS тип как Common.

Но классу B необходимо реализовать IMyInterface, который не содержит общий класс. Таким образом, класс Factory выдает ошибку, что метод интерфейса не существует в Common class.

Как и как лучше всего это решить?

[Изменено]

Прежде всего, @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; 
    } 
} 

В этом случае, я могу думать, я могу определить метод doC() в классе Common. Но также я хочу, чтобы ClassB, C, D и E должны реализовывать метод Doc.

пожалуйста, сообщите мне,

+0

Пожалуйста, смотрите обновление мой ответ для 'класса C' и т.д. случае также – basarat

ответ

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');  
     } 
    } 
} 

Docs

Союз Тип: https://basarat.gitbooks.io/typescript/content/docs/types/type-system.html#union-type

Тип Guard : https://basarat.gitbooks.io/typescript/content/docs/types/typeGuard.html

UPDATE

В соответствии с просьбой, если кто-то хочет, чтобы проверить для интерфейса нужно создать определенный пользователем тип охранник (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');  
     } 
    } 
} 
+0

Вы не должны проверить IMyInterface вместо ClassB? – Bas

+0

интерфейсов не существует во время выполнения и, следовательно, не может использоваться для проверок времени выполнения. – basarat

+0

Можно создать специальный защитник типа, если вам действительно нужно проверить контракт на интерфейс – basarat