TypeScript错误TS2449:在声明之前使用的类'x'

时间:2017-12-06 17:56:13

标签: typescript

我不了解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非常相似,它处理了跨多个文件的模块。

2 个答案:

答案 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的注释中所述