我不了解tsc
关于<reference>
的编译过程,并将命名空间的类拆分为多个文件。我正在使用这种模式:
src/base.ts
namespace MyNameSpace {
export class Base {
/** constructor, etc. */
}
}
src/subclass.ts
/// <reference path="./base.ts" />
namespace MyNameSpace {
export class Subclass {
/** constructor, etc. */
}
}
这个简单的例子有效。但是当我在更多文件上使用该模式时,我会定期收到错误TypeScript error TS2449: Class 'x' used before its declaration.
。
我们是否回到手动管理声明排序,例如.c
/ .h
个文件?如果是这样,有哪些工具可以帮助回溯找到错误的参考?
我的目标是拥有一组可管理的文件,这些文件可以编译成单个.js
和.d.ts
(用于另一个要使用的TypeScript库)。如果这种情况有更好的解决方案?尝试使用Webpack和import
的变体使我失望。
如果重要,我也使用嵌套命名空间,其中成员在子目录中定义。我总是使用相对reference
路径。
这与typescript Base type 'xxxx' is referenced before its declaration非常相似,它处理了跨多个文件的模块。
答案 0 :(得分:5)
命名空间不是首选模块。这是非常重要的一点。让我们深入了解历史......
过去,命名空间的声明如下:
module MyNamespace {
}
但他们现在被宣布为:
namespace MyNamespace {
}
声明命名空间时,namespace
关键字优先于旧的module
关键字。
将module
关键字替换为namespace
的原因是人们将其与“模块”混为一谈。你可以看到混乱的来源!现在实际 modules (i.e. files that export or import something) are actually a bit better than namespaces,这就是为什么到目前为止我已经花了整个答案来覆盖所有这些。
考虑到这一点,您可以考虑使用模块。每个模块都为您提供命名上下文,并使其远离全局范围。您可以导入和导出,一切都应该按预期工作(如果您愿意,您仍然可以捆绑它。)
的src / base.ts
export class Base {
}
的src / subclass.ts
import * as Example from './subclass.ts';
export class Base extends Example.Base {
}
如果你想坚持命名空间,你必须尊重你在命名空间中放置的所有内容(即使该命名空间分布在多个文件中)也会导致单个命名上下文...所以你必须命名子类不同。
的src / base.ts
namespace MyNameSpace {
export class Base {
/** constructor, etc. */
}
}
的src / subclass.ts
/// <reference path="./base.ts" />
namespace MyNameSpace {
export class Sub extends Base {
/** constructor, etc. */
}
}
最终,您可以选择模块(适当的外部模块),其中每个文件都有自己的命名上下文,您可以轻松避免命名冲突 - 或者您需要知道每个命名空间是单个命名上下文的namsepace
在可能的示例中,我在子类中继承了Base
以进行说明。你的问题并不完全是这样,但我想说明这个概念。该问题在命名空间中有两个具有相同名称的类,这是一个重复的名称冲突。
答案 1 :(得分:1)
我能够通过重新启动Visual Studio 来解决此错误,如@ Quentin2的注释中所述