Typescript函数生成一个实现接口的类

时间:2019-09-30 12:46:03

标签: typescript inheritance interface

我的问题是我对打字稿机制不了解:为什么在以下代码中,ComposerA是正确的而ComposerB不是?

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

function ComposerA<T extends Ctor>(Target: T) {
  return class extends Target {
    ...
  }
}

function ComposerB<T extends Ctor>(Target: T) {
  return class implements Target {
    ...
  }
}

在ComposerB中,我得到错误->'Target'指向一个值,但在此处被用作类型。

我认为有一个我不了解的概念。是否有可能实现一个带有对象并实现它的功能。我需要工具而不是扩展,这个示例是我原始代码的简化,并且我已经扩展了另一个类。

1 个答案:

答案 0 :(得分:0)

您无法在运行时implement进行任何操作,但是可以将方法添加到类的原型中,并使用泛型更改构造函数签名:

type Class<T={}> = new (...args: any) => T;

interface Fooable {
    foo(n: number):string
}

function withFoo<T>(k: Class<T>): Class<T & Fooable> {

    k.prototype.foo = function(n: number): string {
        return "foo";
    }

    return k as Class<T & Fooable>;
}

class Blah {
    blah(s: string) {}    
}

let BlahFooable = withFoo(Blah);

let b = new BlahFooable;

b.blah("hey") // ok
b.foo(42) // ok

Play

以一种更通用的方式:

type Class<T={}> = new (...args: any) => T;

function Mixin<T, M extends object>(cls: Class<T>, mixin: M): Class<T & M> {
    Object.assign(cls.prototype, mixin);
    return cls as Class<T & M>;
} 

class Blah {
    blah(s: string) {}
}

let BlahWithFoo = Mixin(Blah, {
    foo(n: number): string {
        return "foo";
    }
});

let b = new BlahWithFoo();

b.blah("hey") // ok
b.foo(42) // ok