什么是mixin类的类型

时间:2017-12-09 18:54:48

标签: typescript

我无法弄清楚如何获得打字稿mixin类的类型而不采取如此一些黑客攻击(如下所示)

type Constructor<T = {}> = new(...args: any[]) => T;

function MyMixin<T extends Constructor>(BaseClass: T) {
  return class extends BaseClass {doY() {}}
}

// Option A: Ugly/wasteful
const MixedA = MyMixin(class {doX() {}});
const dummy = new MixedA();
type MixedA = typeof dummy;

class OtherA {
  field: MixedA = new MixedA();
  a() {this.field.doX(); this.field.doY();}
}

// Option B: Verbose
class Cls {doX() {}}
interface MixinInterface {doY(): void}

const MixedB = MyMixin(Cls);
type MixedB = Cls & MixinInterface;

class OtherB {
  field: MixedB = new MixedB();
  a() {this.field.doX(); this.field.doY();}
}

这是很可悲,我认为打字稿不支持诚实混入/特征,但有一些其他的方式来声明的类型field,而不诉诸TYPEOF实例或是在重新申报签名一个接口(我试过typeof(new MixedBaseA())但是typeof不接受任意表达式)?

1 个答案:

答案 0 :(得分:2)

可能不是你想要的,但这是一个不那么浪费的选择。鉴于定义:

type Constructor<T = {}> = new(...args: any[]) => T;

function MyMixin<T extends Constructor>(BaseClass: T) {
    return class extends BaseClass {
        doY() { }
    }
}

const MixedA = MyMixin(class { doX() {} });

您可以使用以下方式获取类型:

function getReturnType<R>(fn: (new(...args: any[]) => R)): R {
  return {} as R;
}

const dummy = getReturnType(MixedA);
type MixedAType = typeof dummy;

const mixedA : MixedAType = new MixedA();
mixedA.doX();
mixedA.doY();

Playground

获取任何表达类型的提案仍有待讨论:https://github.com/Microsoft/TypeScript/issues/6606。这将摆脱虚拟变量和函数。

或者,要获得干净的type MixedAType = MyMixinY & X,您可以选择在mixin中返回正确的构造函数类型:

type Constructor<T = {}> = new(...args: any[]) => T;

interface MyMixinY {
    doY()
} 

function MixinY<T extends Constructor>(BaseClass: T)
    : Constructor<MyMixinY> & T {

    return <any> class Y extends BaseClass implements MyMixinY {
        doY() { 
            console.log("in Y");
        }
    }
}

const MixedA = MixinY(class X {
    doX() {
        console.log("in X");
    }
});

function getReturnType<R>(fn: (new(...args: any[]) => R)): R {
  return {} as R;
}

const dummy = getReturnType(MixedA);
type MixedAType = typeof dummy; // now is `type MixedAType = MyMixinY & X`

const mixedA: MixedAType = new MixedA();
mixedA.doX();
mixedA.doY();