【问题标题】:TypeScript - get type of constructor of a pure class typeTypeScript - 获取纯类类型的构造函数类型
【发布时间】:2021-05-08 16:22:11
【问题描述】:

我想使用typeof 运算符从类中获取构造函数类型,但是当您想在类字典中使用它时它似乎不起作用。例如。 typeof Modules[T] - 编译器没有得到 Modules[T] 的类型,而是考虑 (typeof Modules)[T]

class A { }

class B { }

abstract class Modules {
    public a!: A;
    public b!: B;
}

// Error: Type 'T' cannot be used to index type 'typeof Modules'
function addModule<T extends keyof Modules>(key: T, ModuleCtor: typeof Modules[T]) {
    let module = new ModuleCtor();
}

addModule('a', A);

// Works but the constructor arguments type is lost
function addModule2<T extends keyof Modules>(
    key: T,
    ModuleCtor: new (...args:any[]) => Modules[T]
) {
    let module = new ModuleCtor();
}

addModule2('a', A);

Playground url

更新

正如 Aleksey 所指出的,typeof 运算符仅适用于值。类是实际值,但我这里有的是纯类型。我本质上是在寻找像 typeof Class (value) 这样工作的东西,它可以获得纯类类型的构造函数的确切类型(包括它的参数)。

【问题讨论】:

  • 你不能将typeof与类型一起使用,它应该与值一起使用。这就是为什么第一次尝试不起作用
  • typeof 可用于获取类构造函数的类型。 typescriptlang.org/play?#code/…
  • 当然,如果你将它与作为值的类/函数一起使用。 Modules[T] 是一个类型
  • 啊哈。现在明白了,谢谢!我现在也明白,我之前的new (...args:any[]) =&gt; Modules[T] 解决方案已经足够好了,因为返回相同事物的类很难拥有不同的构造函数参数。虽然我仍然想知道是否有一个类类型的“typeof”等价物可以得到构造函数的确切类型,包括参数。

标签: javascript typescript typescript-typings


【解决方案1】:

您的第一个问题是您必须记住 Typescript 类型基于界面的形状,而不是硬类型。

所以在你的例子中 -> class A { } 和 class B { } 是同一个类型..

所以我们需要做的第一件事是在您的示例中以某种方式使 A 和 B 不同,以便 Typescript 可以知道差异。

否则你可以这样做 -> addModule('a', B); 我假设你想捕获它。

例如。

class A { A?:string }
class B { B?:string }

在上面,A 类和 B 类类型现在不同了,在实际应用程序中,您的方法等可能不同,因此通常不需要做一个虚拟的 A?:string

接下来的问题是我们需要定义构造函数的形状,如果你的构造函数是空的,一个简单的例子是->

type Construct&lt;T&gt; = new () =&gt; T;

这样做之后,我们的最终结果是 ->

class A {
    A?: string
}

class B {
    B?: string
}

class Modules {
    a!: A;
    b!: B;
}

type Construct<T> = new () => T;

function addModule<T extends keyof Modules, C extends Construct<Modules[T]>>(key: T, ModuleCtor: C) {
  const x = new ModuleCtor()
}

var a = addModule('a', A)

//Argument of type 'typeof B' is not assignable to parameter of type 'Construct<A>'.
var a = addModule('a', B)

Playground

【讨论】:

  • new () =&gt; T - 这只有在我们假设构造函数不接受任何参数时才有效。我的问题中有这个:ModuleCtor: new (...args:any[]) =&gt; Modules[T] - 它更通用,因为它可以使用或不使用参数。我本质上是在寻找可以得到类的确切类型的东西,直到确切的构造函数参数。 typeof 可以做到这一点,如果类是一个实际值,我正在为纯类类型寻找相同的解决方案。
猜你喜欢
  • 1970-01-01
  • 2016-04-05
  • 1970-01-01
  • 2017-09-14
  • 1970-01-01
  • 2022-06-25
  • 2017-05-28
  • 2016-08-21
相关资源
最近更新 更多