如何扩展具有通用类型和不同构造函数的2个类?

时间:2019-04-26 06:33:18

标签: typescript

我正在关注此示例=>

Typescript: How to extend two classes?

就我而言,我想扩展一个主类=>

shift + cmd + k

export class MyClassOne {
   constructor(param1, param2)
}

所以我尝试了以下

MyClassTwo<F extends interface1, O extends interface2>{
        constructor(param3, param4)
}

它可以工作,但是我不知道设置我的泛型类型的方法。因为如果我在<>内有任何东西

  

“ typeof MyClassTwo”类型的值不可调用。你是否   打算包含“新”?

3 个答案:

答案 0 :(得分:1)

这是一个扩展泛型类的简单示例,您可以使用相同的方式对泛型类型进行多次扩展,甚至还可以初始化或创建实例:

class BeeKeeper {
    hasMask: boolean;
}

class ZooKeeper {
    nametag: string;
}

class Animal {
    numLegs: number;
}

class Bee extends Animal {
    keeper: BeeKeeper;
}

class Lion extends Animal {
    keeper: ZooKeeper;
}

function createInstance<A extends Animal>(c: new () => A): A {
    return new c();
}

createInstance(Lion).keeper.nametag;  // typechecks!
createInstance(Bee).keeper.hasMask;   // typechecks!

答案 1 :(得分:1)

您需要使用泛型来确保将原始类的类型转发到函数的输出。 here概述了此模式。

此代码将按预期工作,并在输出中保留所有类型参数

const addMyClassOneInheritance = <T extends new(...args: any[]) => any>(MyClassOne: T)=> {
    return class extends MyClassOne { };
}

class MyClassTwo<F extends string, O extends number>{
    constructor(param3: F, param4: O) { }
}
const MyFinalClass = addMyClassOneInheritance(MyClassTwo);

export class SynchMapComponent extends MyFinalClass<string, number> {
}


new SynchMapComponent("", 1)

答案 2 :(得分:1)

虽然mixins通常是一个非常好的概念,但我认为它们并没有真正解决将单个class中扩展两个的问题。相反,它们通过一组固定的额外功能来增强 one 类。实际上,我认为不可能在一个单一的类中扩展两个不同的,不相关的类。但是假设我们接受两个较小的住宿条件,我们可以很接近:

  1. 由于原型链是线性的,因此扩展类的实例只能是其instanceof的一位祖先(假设是第一个)。
  2. 由于TypeScript类只能实现具有静态已知成员的接口(并且没有通用类型变量),因此无法创建以通用方式扩展另外两个class的接口。我们将改为使用工厂功能。

现在,看看以下功能:

type Constructable = new (...args: any[]) => any;

const mergeClasses = <S extends Constructable, T extends Constructable>(class1: S, class2: T) =>
    <Si extends InstanceType<S> = InstanceType<S>, Ti extends InstanceType<T> = InstanceType<T>>
    (args1: ConstructorParameters<S>, args2: ConstructorParameters<T>): Si & Ti => {
        const obj1 = new class1(...args1);
        const obj2 = new class2(...args2);
        for (const p in obj2) {
            obj1[p] = obj2[p];
        }
        return obj1 as Si & Ti;
    };

调用它将返回一个工厂函数,该函数构造实现最初传递给mergeClasses的两个类的对象实例。例如扩展两个类

class MyClassOne {
    constructor(param1: number, param2: number) { }
}

class MyClassTwo<F, O> {
    constructor(param3: number, param4: number) { }
}

您只需编写以下内容(如果它们不是通用的,则忽略类型参数):

const instanceFactory = mergeClasses(MyClassOne, MyClassTwo);
const instance = instanceFactory<MyClassOne, MyClassTwo<number, string>>([1, 2], [3, 4]);

您还可以签出示例代码here