【问题标题】:TypeScript Generics: Function that returns constructor of instance specified as parameterTypeScript 泛型:返回指定为参数的实例的构造函数的函数
【发布时间】:2020-01-25 11:36:07
【问题描述】:

我正在学习 TypeScript。我一直在研究泛型,但遇到了一个小问题,我正在努力寻找答案。

我已经在 Google 上搜索了很多搜索查询,但由于搜索词的含糊不清,以及对某些语言结构的技术名称缺乏了解,我得到了很多噪音。

我在 TypeScript 的网站上阅读了三个相关页面的文档,但找不到我需要的信息。也许我忽略了一些东西,如果是这样的话,一个好的解释的链接将不胜感激。

我想编写一个函数,它返回指定为保留类型参数的实例的构造函数,因为 TypeScript 中的 this.constructor 不是类的类型。

非常清楚,我知道我可以做到这一点:

const aa2 = (a.constructor as typeof A).make();

这是一个精简的案例:

class A {
    prop1: string;
    prop2: number;

    constructor(prop1: string, prop2: number) {
        this.prop1 = prop1;
        this.prop2 = prop2;
    }

    method() {

    }

    static make() {
        return new this('test', 42);
    }
}

function constructor<T>(instance: T): { new(...args): T } {
    return instance.constructor as { new(...args): T };
}

const a = A.make();

// Property 'make' does not exist on type 'new(...args: any[]) => A'
const aa = constructor(a).make();


// This works, but is not pretty
const aa2 = (a.constructor as typeof A).make();

它需要在任何类上工作,有或没有构造函数参数。

我可以反过来:

export function make<T>(type: { new(...args): T }, ...args): T {
    return new type(...args);
}

make(A, 'test', 42).method();

这似乎有一些我没有得到的关键因素。如果你能准确地发现我的想法哪里出了问题,我欢迎对我的误解做出一个很好的解释。

【问题讨论】:

  • 为什么需要获取构造函数?
  • @BunyaminCoskuner - 为什么不重要。我有一个问题,我正在寻找答案。我知道您可能正在思考我的用例是,以及我的用例本身是否是一个误解,以便您可以纠正它。当我发现问题的答案是“你为什么这样做”时,我觉得有点烦人。我的理由可能有效,也可能无效,但这并不重要,这仍然是一个有效的问题。即使该解决方案不适合我的用例,也可能适用于找到此问题答案的其他人。
  • 我问这个问题是为了进一步了解您的问题。有一个东西叫XY Problem,有时我们,试图在这里回答问题的人,可能无法理解OP的真正意图。我遇到了几个问题,解决方案比 OP 尝试做的更简单。所以,我的问题和你的一样有效。所以,“为什么”确实很重要
  • 一切都很好 :) 我知道为什么这类问题会激怒人们,我同意这里有一些居高临下的人。回到主题,this 之类的内容会帮助您解决问题吗?
  • 不客气,希望您能提出一个完全可行的解决方案 :)

标签: typescript generics typescript-generics


【解决方案1】:

没有办法从实例类型转移到类类型。这只有在 constructor 被键入为类类型时才有可能(事实并非如此)有一张公开票可以制作 this happen 但它已经公开并讨论了很长时间。

如果您控制客户端类,则可以向该类添加成员以使该方法正常工作:

class TraceableClass<TThis> {
  private typedConstructor!: TThis
}
class A<TThisClas = typeof A> extends TraceableClass<TThisClas>{
    prop1: string;
    prop2: number;

    constructor(prop1: string, prop2: number) {
        super();
        this.prop1 = prop1;
        this.prop2 = prop2;
    }

    method() {

    }

    static make() {
        return new this('test', 42);
    }
}

function constructor<T>(instance: TraceableClass<T>): T {
    return instance.constructor as  any as T;
}

const a = A.make();

// Ok now
const aa = constructor(a).make();


Play

【讨论】:

  • 我明白了,我很高兴有办法,但很失望,因为它感觉很复杂。我想现在我会继续投射this.constrcutor。感谢您的时间和专业知识。
  • @thephpdev 欢迎您,抱歉我没有更好的消息。至少现在你知道了:)
猜你喜欢
  • 2019-05-04
  • 1970-01-01
  • 2016-04-05
  • 2022-12-21
  • 2017-10-27
  • 2021-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多