如何正确键入返回 TypeScript 中的类的函数?

Posted

技术标签:

【中文标题】如何正确键入返回 TypeScript 中的类的函数?【英文标题】:How can I correctly-type a function that returns a class in TypeScript? 【发布时间】:2019-09-02 07:47:41 【问题描述】:

在 TypeScript 中,class 关键字同时引入了值和类型:

class Plain  ;
const plain: Plain = new Plain();

有没有办法让函数返回既是类型又是值的东西?

问这个问题的另一种方式是:有没有办法在下面声明createClass 的类型以便const a2: Animal = new Animal() 进行类型检查?

declare function createClass<T extends string>(t: T): (new () =>  type: T );

const Animal = createClass("animal");

const a1         = new Animal();
const a2: Animal = new Animal(); // Error: 'Animal' refers to a value, but is being used as a type here.
const a3: InstanceType<typeof Animal> = new Animal(); // OK but verbose, even if I make a type alias

See this TypeScript Playground

【问题讨论】:

【参考方案1】:

一个类声明产生一个类型和一个值。该值是类的构造函数(这就是为什么在表达式中编写new Plain() 时调用构造函数的原因)。类型,与类同名,表示类的实例类型(这就是你可以在类型注解中使用它的原因)

另一方面,const 只是一个值,即使它确实包含一个类。没有对应的类型。实现与类声明类似功能的唯一方法是创建具有相同名称的类型别名。

declare function createClass<T extends string>(t: T): (new () =>  type: T );

const Animal = createClass("animal");
type Animal = InstanceType<typeof Animal>

const a1         = new Animal(); 
const a2: Animal = new Animal(); 

类型的值位于不同的域中,因此使用相同的名称即可。

不幸的是,没有办法在单个语句中做到这一点,这涉及到一些冗长。

【讨论】:

感谢您的回答。我认为它是正确的,但我认为它没有说明任何问题。你有引用吗? 我认为官方文档中没有任何引用,这只是值空间和类型空间如何工作的结果(更详细的解释在这里:***.com/questions/51131898/…)。你可以在 GitHub 上搜索更官方的答案,如果我找到了,我会在这里发布。

以上是关于如何正确键入返回 TypeScript 中的类的函数?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 TypeScript 中键入带有类的数组?

如何使用 TypeScript 正确键入 Sequelize JOIN?

如何在 TypeScript 3+ 中正确键入通用元组剩余参数?

如何使用 Typescript 在 mongoose 中正确键入对象 ID 数组

如何使用 Typescript 在 mongoose 中正确键入对象 ID 数组

如何使用 TypeScript 正确键入检查允许部分子树的嵌套记录?