简体   繁体   English

Typescript function 生成实现接口的 class

[英]Typescript function to generate a class implementing an interface

My question is on a point I don't understand in a mechanism of typescript: why in the following code, ComposerA is correct and ComposerB is not?我的问题是关于 typescript 的机制我不理解的一点:为什么在下面的代码中,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 {
    ...
  }
}

In ComposerB I obtain the error -> 'Target' refers to a value, but is being used as a type here.在 ComposerB 中,我得到错误 -> 'Target' 指的是一个值,但在这里被用作一种类型。

I think there is a concept I haven't understood.我想有一个我不明白的概念。 Is it possible to realize a function which take an object and implements it.是否可以实现采用 object 并实现它的 function。 I need implements and not extends, this example is a simplification of my original code and I've already an extend of another class.我需要实现而不是扩展,这个例子是我原始代码的简化,我已经扩展了另一个 class。

You cannot implement anything at run time, but you can add methods to the prototype of the class and change the constructor signature with generics:您不能在运行时implement任何东西,但您可以向 class 的原型添加方法,并使用 generics 更改构造函数签名:

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

In a more generic way:以更通用的方式:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM