typescript 打字稿多重继承
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40807808/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Typescript multiple inheritance
提问by Vayrex
I'm need of multiple inheritance in typescript. Logically it is not good to put a lot of functionality to hierarchy. I have one base class and number of hierarchy branches. But I need somehow to use mixings to put some main logic in separate classes, cuz it is not used in every branch.
我需要打字稿中的多重继承。从逻辑上讲,将很多功能放在层次结构中并不好。我有一个基类和多个层次结构分支。但是我需要以某种方式使用混合将一些主要逻辑放在单独的类中,因为它不是在每个分支中都使用。
UPDATE of code exmple:
代码示例的更新:
function Mixin = function(mixins:any[]){ // mixin decorator
return function(target){
mixins.forEach((mixin) => {
add every function from mixing to target prototype,
if functions with same name does not exists there,
so we are able to do calls to as example different render() functions
Will show it in OpenableItem
});
}
}
function element = function(){
return function(target){
target.prototype.element = function(){
return this.$el;
}
}
}
--------------------------------------------------------------------------------------
@element // every item will have this function as Root as Openable
class BaseItem{
y() => number; // we need to get y position of every item
}
OpenableMixin{
render() => render arrow only
open(){} => change arrow position and cause menu to fire change event
close(){} => change arrow position and cause menu to fire change event
}
class ItemsMixin extends OpenableMixing{// for now if item have childs it must be openable,
// but Responsive has only tasks and must be openable too
addItem(item: BaseItem) // need to add generics
removeItem(item: BaseItem)
}
--------------------------------------------------------------------------------------
@Mixin([ItemsMixin, ActivitiesMixin]) // it can have items and activities
class OpenableItem extends BaseItem implement ItemsMixin, ActivitiesMixin { // as in typescript docs
render(){
// call rendering from BaseItem class
super.render();
// call rendering from OpenableMixing
OpenableMixin.prototype.render.call(this);
// do some separate rendering for OpenableItem only
this.$el.append('line');
}
}
@Mixin([ItemsMixin]) // it can have items
class RootItem extends BaseItem implement ItemsMixin{ // and subitems functionality is only for Root class
subitems: Array<BaseItem> // need to add generics to be able to put here different item types
}
--------------------------------------------------------------------------------------
@element
class Menu{
items: Array<Item>
}
@element
class Timeline{
menu: Menu
listAllelement() => {
console.log(this.element());
console.log(this.menu.element());
this.menu.items.forEach((item) => {
console.log(item.element());
if(item.hasChilds()){ // really it must be (item instanceof RootItem || item instanceof OpenableItem)
item.items.forEach((subitem) => { // really we need some recursion here
console.log(subitem.element());
})
}
})
}
}
In reality it is rare situation when you need to implement multiple inheritance, and it is much rarely when you can have such an issue in javascript. But every item can have different functionality depending on needs.
实际上,需要实现多重继承的情况很少见,而在 javascript 中遇到此类问题的情况也很少见。但是每个项目都可以根据需要具有不同的功能。
Just imagine that there can be different items which can have number of mixins. Is it wise to put everything into base ? And what is your approach to this issue ?
想象一下,可以有不同的项目可以有多个混合。将所有内容都放入 base 是否明智?你对这个问题的态度是什么?
回答by Alex
Currently, TypeScript does not have any special syntax to express multiple inheritance or mixins, but the official workaround can be found here.
目前,TypeScript 没有任何特殊的语法来表达多重继承或混合,但可以在这里找到官方的解决方法。
That strategy is basically that you let your main class implementthe classes that you want, write simple dummy implementation for their interfaces, and then have a special function that reads your classes and overwrites the properties in your main class.
这个策略基本上是让你的主类实现你想要的类,为它们的接口编写简单的虚拟实现,然后有一个特殊的函数来读取你的类并覆盖你的主类中的属性。
There are some suggestions to make TypeScript better at mixins/traits, eg. #2919and #311.
回答by Simon Epskamp
@kjetil-klaussen is correct, typescript 2.2 added support for the ECMAscript 2017 mixin pattern
@kjetil-klaussen 是正确的,typescript 2.2 添加了对ECMAscript 2017 混合模式的支持
Here is a full code sample:
这是一个完整的代码示例:
// http://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/
// https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#support-for-mix-in-classes
type Constructor<T> = new (...args: any[]) => T;
class S {
foo() {
console.log('foo from S');
}
}
// Here the possible SuperClass is set to {} (Object)
function Mixin1<T extends Constructor<{}>>(SuperClass: T) {
return class extends SuperClass {
foo() {
console.log('foo from Mixin1');
if (super.foo) super.foo();
}
};
}
// Here the possible SuperClass (S) is specified
function Mixin2<T extends Constructor<S>>(SuperClass: T) {
return class extends SuperClass {
foo() {
console.log('foo from Mixin2');
super.foo();
}
};
}
class C extends Mixin1(Mixin2(S)) {
foo() {
console.log('foo from C');
super.foo();
}
}
new C().foo();
This outputs:
这输出:
foo from C
foo from Mixin1
foo from Mixin2
foo from S
回答by Kjetil Klaussen
Typescript 2.2 added support for mix-ins.
Typescript 2.2 添加了对 mix-ins 的支持。