这是简化的代码
export interface MyInterface{
// Have no idea why I need an export here.
// If I remove it, it gives
// semantic error TS2451 Cannot redeclare block-scoped variable 'createClass'
}
const createClass = function () {
return class implements MyInterface{
}
};
const MyClass = createClass();
// this line is fine
const mi: MyInterface = new MyClass();
// this is where I concerned. It gives semantic error TS2304 Cannot find name 'MyClass'
const mc: MyClass = new MyClass();
那么如何在类型注释中使用名称 MyClass 呢? 我的 TypeScript 版本是 3.2.2
最佳答案
TL;DR
为 MyClass
添加类型定义
const MyClass = createClass();
type MyClass = InstanceType<typeof MyClass>
说明
考虑以下简单的类声明:
class MyClass {}
const mc: MyClass = new MyClass()
当您使用 class
关键字声明一个类时,编译器知道两件事。在当前范围内,有一个具有能够构造该类的类名称的值(即 MyClass 构造函数),并且与该类同名的类型也将存在于表示类的实例类型的当前范围(在本例中为 MyClass
类型)。看这个answer对于值空间与类型空间。
由于您在函数中声明了该类,即使您要给它一个名称,它也只能在函数内部访问(基本作用域规则)。该接口(interface)是可访问的,因为它在同一范围内(假设所有内容都在同一个文件中)或显式导入(如果您在另一个模块中)。
当您使用返回的函数并将其分配给 const
(const MyClass = createClass();
) 时,您只做了 class 的一半
声明就可以了,你告诉编译器存在一个名为 MyClass
的构造函数。编译器不会为 MyClass
的实例类型添加任何类型(为什么会这样,const
的赋值通常不会引入新类型,而只是引入新值)。
简单的解决方案是完成另一半工作,添加一个同名的类型,该类型将作为返回类的实例类型。这两个名称不会冲突,因为一个位于值空间(const
),另一个位于类型空间(type
)
const MyClass = createClass();
type MyClass = InstanceType<typeof MyClass>
const mc: MyClass = new MyClass(); // Ok now.
注意 我假设您在函数内声明该类,并以问题中不明显的原因返回它,如果您不只是使用类声明。
关于typescript - 如何在类型注释中使用函数返回的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53826687/