我试图定义一个基于纯类的mixin函数,但我无法获得适合此类型的类型签名。
目的是提供一个接受任何A类作为参数的函数,并返回一个扩展原始A类的新B类。
export function mixin<A>(myclass: A) {
return class B extends A {
newMethod() {
//stuff
}
}
}
正如我所说,我无法弄清楚这一点。
我还需要表达返回类型,它会产生几个错误:
错误TS4060:导出函数的返回类型具有或正在使用私有名称“B”。
其他信息:
utils.ts
模块中,以便其他模块可以使用它答案 0 :(得分:5)
我想在TypeScript 2.2中使用mixins和
@Parameter
)上的Feature
)和mixin应用程序(Derived
)
"declaration": true
)我开始使用以下代码,但遗憾的是不起作用:
export type Constructor<T> = new(...args: any[]) => T;
export abstract class AbstractBase {
fieldA = "a";
}
export function Feature<T extends Constructor<object>>(Base: T) {
return class extends Base {
@Parameter()
fieldB = "b";
};
}
export class Derived extends Feature(AbstractBase) {
fieldC = "c";
}
最后,我最终得到了以下代码,这些代码更复杂,但按预期工作:
export type Constructor<T> = new(...args: any[]) => T;
export abstract class AbstractBase {
fieldA = "a";
}
export interface Feature {
fieldB: string;
}
export function Feature<T extends Constructor<object>>(Base: T): T & Constructor<Feature> {
class TWithFeature extends Base implements Feature {
@Parameter()
fieldB = "b";
}
return TWithFeature;
}
export const AbstractBaseWithFeature = Feature(AbstractBase as Constructor<AbstractBase>);
export class Derived extends AbstractBaseWithFeature {
fieldC = "c";
}
除了@bruno-grieder的回答,请参阅以下链接:
答案 1 :(得分:4)
这个问题有一个未解决的问题: Allow class to extend from a generic type parameter
现在你可以解决这个问题:
interface Base{}
interface BaseClass<T> {
new (): T
readonly prototype: T;
}
function mixin<T extends Base>(baseClass: BaseClass<T>) {
class B extends (baseClass as BaseClass<Base>) {
newMethod() { }
}
return B as BaseClass<T & B>;
}
这是基于此处的代码:extends dynamic Base class with generic throw an error
您可以为新类添加的方法定义接口,例如:
interface B {
newMethod(): void;
}
function mixin<T extends Base>(baseClass: BaseClass<T>): BaseClass<T & B> {
class BImpl extends (baseClass as BaseClass<Base>) implements B {
newMethod() {
console.log("B.newMethod");
}
}
return BImpl as BaseClass<T & B>;
}
然后您可以导出B
界面,然后您可以在任何地方使用它
这段代码效果很好:
class A implements Base {
method() {
console.log("A.method");
}
}
let NewA = mixin(A);
let newA = new NewA();
newA.method();
newA.newMethod();
输出:
A.method
B.newMethod
答案 2 :(得分:1)
使用Typescript 2.2.1,我在@Nitzan Tomer解决方案中遇到了(主要是导出和可见性)问题而不得不诉诸于此,我相信它更接近mixin documentation并使我的(Webstorm)IDE更智能
export interface Constructor<T> {
new( ...args: any[] ): T
}
export interface B {
newMethod(): void;
}
export const mixin = <T extends Constructor<{}>>( baseClass: T ) =>
class BImpl extends baseClass implements B {
newMethod() {
console.log( "B.newMethod" );
}
} as Constructor<B> & T
import {B, Constructor, mixin} from './mixin'
class A {
method() {
console.log( "A.method" )
}
}
const AB: (typeof A) & Constructor<B> = mixin( A )
const ab = new AB()
ab.method()
ab.newMethod()