打字稿泛型类参数 [英] Typescript generic class parameters

查看:32
本文介绍了打字稿泛型类参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在为项目编写一些内部抽象类,我需要它是通用的(我希望它是可扩展的).

I am currently programming some internal abstract class for project and I need it to be generic (I want it to be extendable).

我希望我的类被调用,因为它会扩展 T 模板,如 Sample extends T,以便拥有 T 的所有参数.例如,如果 T 是 Vue,我将拥有所有 Vue 参数,例如 $el$options 而不重新声明 Vue 或包含它.

I want my class to be called as it would extend the T template like Sample extends T, in order to have all the parameters of T. For example if T is Vue, I would have all Vue parameters such as $el or $options without re-declaring Vue nor including it.

所以我有以下内容:

export namespace SDK {

  export abstract class Sample<T> {

    private static methods: any = {
      hello: Sample.prototype.hello
    }

    abstract callMe () : void;

    x: number = 0
    y: number = 0
    width: number = 1
    height: number = 1

    hello (): void {
      console.log('Sample hello world')
      this.callMe()
    }
  }
}

但是我不知道如何处理才能将 T 的属性包含到 Sample 中.

But I don't know how to process to include the properties of T into Sample.

我希望它是这样的:

export namespace SDK {

  export abstract class Sample<T> {

    private static methods: any = {
      hello: Sample.prototype.hello
    }

    abstract callMe () : void;

    x: number = 0
    y: number = 0
    width: number = 1
    height: number = 1

    // T properties (Vue example)
    $el: HTMLElement
    ...

    hello (): void {
      console.log('Sample hello world')
      this.callMe()
    }
  }
}

我希望我的班级被称为:

I would like my class to be called like:

export default class MyComponent extends SDK.Sample<Vue> {
  name: string = 'my-component';

  callMe () : void {
    console.log('called')
  }

  mounted () : void {
    this.hello()
  }
}

我没有找到任何关于从允许在其中包含参数的模板化类进行扩展的内容.

I did not find anything about extending from a templated class that allow to have parameters in it.

推荐答案

我认为 @TitianCernicovaDragomir 使用 mixins 基本上是正确的.为了完整起见,我将发布类似的代码,因为我认为我们采用了略有不同的方法,并且它们有一些不同的优点和缺点.

I think @TitianCernicovaDragomir basically has it right using mixins. I have similar code that I will post for completeness, since I think we took slightly different approaches and they have somewhat different advantages and disadvantages.

以下代码确实强制您实现了 abstract 方法并允许您访问静态成员.但是您通过使用私有的未导出名称为此付出了代价,这最终会阻止您将其变成供其他人使用的库.我认为有一些解决方法,但我不想在这个问题上走得太远.

The following code does enforce that you implement abstract methods and gives you access to static members. But you pay for that by using private unexported names that end up preventing you from making this a library for consumption by others. I think there are workarounds but I don't want to go too far down a rabbit hole with this.

无论如何,这是示例:

export namespace SDK {

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

  export function Sample<C extends Constructor<{}>>(ctor: C) {
    abstract class Sample extends ctor {
      private static methods: any = {
        hello: Sample.prototype.hello
      }
      abstract callMe(): void;
      x: number = 0
      y: number = 0
      width: number = 1
      height: number = 1

      hello(): void {
        console.log('Sample hello world')
        this.callMe()
      }

    }
    return Sample;
  }

}

及其用法:

export default class MyComponent extends SDK.Sample(Vue) {
  name: string = 'my-component';

  callMe () : void {
    console.log('called')
  }

  mounted () : void {
    this.hello()
  }
}

祝你好运!

这篇关于打字稿泛型类参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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