使用 Typescript 实现纯类混合 [英] Implement Pure Class mixins with Typescript

查看:50
本文介绍了使用 Typescript 实现纯类混合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试定义一个基于纯类的 mixin 函数,但我无法获得适合该函数的类型签名.

Im trying to define a pure class based mixin function, but I cannot get the type signature right for this one.

目的是提供一个函数,该函数接受任何 A 类作为参数,并返回一个扩展了原始 A 类的新 B 类.

The intent is to provide a function that accepts any Class A as parameter and returns a new Class B that extends the original Class A.

export function mixin<A>(myclass: A) {
  return class B extends A {
    newMethod() {
      //stuff
    }
  }
}

正如我所说,我无法弄清楚这一点.

As I said, I cannot figure this out.

  • 我需要一种方法来表达 A 需要是一个类.

  • I need a way to express that A needs to be a class.

我还需要表达返回类型,这会产生几个错误,其中:

I also need to express the return type, which yields several errors, among:

错误 TS4060:导出函数的返回类型具有或正在使用私有名称B".

error TS4060: Return type of exported function has or is using private name 'B'.

附加信息:

  • 这是在一个 utils.ts 模块中,该模块被导出以便其他模块可以使用它
  • 这一切都是在我正在编写的库的上下文中进行的
  • This is inside a utils.ts module that is exported so that other modules can use it
  • This is all being worked in the context of a library I am writing

推荐答案

这里有一个未解决的问题:允许类从泛型类型参数扩展

There's an open issue for this one: Allow class to extend from a generic type parameter

现在你可以用这样的方法解决这个问题:

For now you can work around that with something like this:

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>;
}

(代码在操场上)

基于此处的代码:扩展动态基类并引发错误

您可以为新类添加的方法定义一个接口,例如:

You can define an interface for the methods which will be added by the new class, something like:

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接口,然后就可以在任何地方使用了.
此代码运行良好:

Then you can export the B interface and then you can use it anywhere.
This code works well:

class A implements Base {
    method() {
        console.log("A.method");
    }
}

let NewA = mixin(A);
let newA = new NewA();
newA.method();
newA.newMethod();

输出:

A.方法
B.新方法

A.method
B.newMethod

这篇关于使用 Typescript 实现纯类混合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆