Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 在node.js中将mixin与泛型组合_Typescript_Generics_Mixins - Fatal编程技术网

Typescript 在node.js中将mixin与泛型组合

Typescript 在node.js中将mixin与泛型组合,typescript,generics,mixins,Typescript,Generics,Mixins,我正在开发一个库,我希望为相同的库方法支持一些不同的扩展。 以下是我的简短混音代码,仅供您参考: type Creator<T = {}> = new (...args: any[]) => T; class DefaultCreator { world:string[] = []; someMagic() { this.world.push("magic") } getWorldList(

我正在开发一个库,我希望为相同的库方法支持一些不同的扩展。
以下是我的简短混音代码,仅供您参考:

type Creator<T = {}> = new (...args: any[]) => T;
class DefaultCreator {
        world:string[] = [];
        someMagic() {
            this.world.push("magic")
        }
        getWorldList() {
            return this.world;
        }
}

function PlantCreator<TBase extends Creator>(Base: TBase) {
    return class extends Base {
        private world = (<DefaultCreator><any>this).world;
        createPlant() {
            this.world.push("Plant")
        }
    };
}

function AnimalCreator<TBase extends Creator>(Base: TBase) {
    return class extends Base {
        private world = (<DefaultCreator><any>this).world;
        createDog() {
            this.world.push("Dog")
        }
    };
}
我现在的问题是,如何创建一个从上面获取“MyWorld”的类

abstract class Playground {
    abstract createWorld(creator: DefaultCreator);
    play() {
        this.createWorld(new DefaultCreator());
    }
}

我的想法是,实现可以使用框架特性(这里只需播放)并使用定制的创建者(aka Builder)创建世界。我尝试了泛型,但无法编译。我做错了什么?

这似乎是不可能的。因为
MyWorld
不是一个类型,它更像是一个奇怪的类型描述

当我让我的想法指定类型时,我得到这一行:

const MyWorld: { new(): ({ world: string[]; createDog(): void } & any); prototype: { world: string[]; createDog(): void } } = AnimalCreator(PlantCreator(DefaultCreator));
我的解决方案是按约定强制用户创建实例,并返回示例的
世界

我修改了我的游乐场,以便获得以下代码:

abstract class Playground {
    abstract createWorld(): string[];
    play() {
        console.log("Creating world containing:");
        this.createWorld().forEach(item => console.log(`- ${item}`))
    }
}

class MyPlayground extends Playground {
    createWorld(): string[] {
        const world = new MyWorld();
        world.someMagic();
        world.createPlant();
        world.createDog();
        return world.getWorldList();
    }
}

new MyPlayground().play();
上述代码的输出:

创建包含以下内容的世界:
-魔法
-植物
-狗


这似乎是不可能的。因为
MyWorld
不是一个类型,它更像是一个奇怪的类型描述

当我让我的想法指定类型时,我得到这一行:

const MyWorld: { new(): ({ world: string[]; createDog(): void } & any); prototype: { world: string[]; createDog(): void } } = AnimalCreator(PlantCreator(DefaultCreator));
我的解决方案是按约定强制用户创建实例,并返回示例的
世界

我修改了我的游乐场,以便获得以下代码:

abstract class Playground {
    abstract createWorld(): string[];
    play() {
        console.log("Creating world containing:");
        this.createWorld().forEach(item => console.log(`- ${item}`))
    }
}

class MyPlayground extends Playground {
    createWorld(): string[] {
        const world = new MyWorld();
        world.someMagic();
        world.createPlant();
        world.createDog();
        return world.getWorldList();
    }
}

new MyPlayground().play();
上述代码的输出:

创建包含以下内容的世界:
-魔法
-植物
-狗


事实上,你离这里不远,但是你模糊了类型和值之间的界限。幸运的是,Javascript/Typescript允许您这样做

//只匹配一个构造函数
类型Creator=new(…args:any[])=>T;
//匹配实际的类
接口创建者类{
新(…args:any[]):T;
}
类DefaultCreator{
世界:字符串[]=[];
神奇的东西{
这个。世界。推(“魔术”)
}
getWorldList(){
回归这个世界;
}
}
函数PlantCreator(基:TBase){
返回类扩展了基{
私人世界=(这个)世界;
createPlant(){
这个。世界。推动(“植物”)
}
};
}
功能动物创造者(基地:TBase){
返回类扩展了基{
私人世界=(这个)世界;
createDog(){
这个。世界。推(“狗”)
}
};
}
界面IPlantWorld{
createPlant():void;
}
IAnimalWorld接口{
createDog();
}
const MyWorld:CreatorClass=AnimalCreator(PlantCreator(DefaultCreator));
抽象班操场{
//我想要类的构造函数的引用
createOtherWorld(创建者:创建者){
返回新的创建者();
}
//我想引用类本身
createWorld(创建者:CreatorClass):T{
将新创建者()返回为T;
}
play(){
这个.createWorld(DefaultCreator);
}
}
班级一切游乐场工厂延伸游乐场{
play(){
//提供类型信息
返回这个.createWorld(MyWorld);
}
}
设pg=neweverythingplaygroundfactory();
让世界=pg.createWorld(MyWorld);
createPlant();
createDog();
pg.createOtherWorld(MyWorld.prototype.constructor);
这可能更符合您所寻找的内容

需要注意的是:


type Creator=new(…args:any[])=>T
只能引用任何类的实际构造函数,但永远不会匹配整个类/类对象。始终记住,类/函数是可执行对象。

实际上,你离目标不远,但你模糊了类型和值之间的界限。幸运的是,Javascript/Typescript允许您这样做

//只匹配一个构造函数
类型Creator=new(…args:any[])=>T;
//匹配实际的类
接口创建者类{
新(…args:any[]):T;
}
类DefaultCreator{
世界:字符串[]=[];
神奇的东西{
这个。世界。推(“魔术”)
}
getWorldList(){
回归这个世界;
}
}
函数PlantCreator(基:TBase){
返回类扩展了基{
私人世界=(这个)世界;
createPlant(){
这个。世界。推动(“植物”)
}
};
}
功能动物创造者(基地:TBase){
返回类扩展了基{
私人世界=(这个)世界;
createDog(){
这个。世界。推(“狗”)
}
};
}
界面IPlantWorld{
createPlant():void;
}
IAnimalWorld接口{
createDog();
}
const MyWorld:CreatorClass=AnimalCreator(PlantCreator(DefaultCreator));
抽象班操场{
//我想要类的构造函数的引用
createOtherWorld(创建者:创建者){
返回新的创建者();
}
//我想引用类本身
createWorld(创建者:CreatorClass):T{
将新创建者()返回为T;
}
play(){
这个.createWorld(DefaultCreator);
}
}
班级一切游乐场工厂延伸游乐场{
play(){
//提供类型信息
返回这个.createWorld(MyWorld);
}
}
设pg=neweverythingplaygroundfactory();
让世界=pg.createWorld(MyWorld);
createPlant();
createDog();
pg.createOtherWorld(MyWorld.prototype.constructor);
这可能更符合您所寻找的内容

需要注意的是:


type Creator=new(…args:any[])=>T
只能引用任何类的实际构造函数,但永远不会匹配整个类/类对象。始终记住类/函数是可执行对象。

您提供了一个有趣的解决方案。所以你在一个接口中放了一个构造函数来创建新的实例,对吗?如果这是真的:酷把戏!然而,您忽略了一个事实,即游乐场是一个抽象类,每个自定义实现都应该使用自己的创建者。当我修改
createWorld
函数时,我无法使用
PlantCreat中定义的方法