【问题标题】:TypeScript: Module x cannot merge with previous declaration of x in a different fileTypeScript:模块 x 不能与之前在不同文件中的 x 声明合并
【发布时间】:2013-12-16 15:39:35
【问题描述】:

我有一个打字稿项目,其中一个模块被拆分为多个文件。有一个与该模块同名的类通过声明合并获取嵌套类,但编译器抛出错误: Bar.ts(1,1): error TS2188: Module 'Foo' cannot merge with previous declaration of 'Foo' in a different file 'path/to/my/file/Foo.ts'.

文件'Foo.ts'

class Foo {
    constructor() {

    }
}

文件'Bar.ts'

module Foo {
    export class Bar {
        constructor() {

        }
    }
}

我正在使用tsc Foo.ts Bar.ts --declaration --out foo.js进行编译

我的主要问题是,我希望能够在我的 Foo 类中使用 var bar = new Bar();,声明合并应该在我的脑海中提供(语言规范在这里并没有真正帮助我)。现在我必须使用var bar = new Foo.Bar();,这很烦人。

是我做错了什么还是编译器错误?

顺便说一句,--declaration 似乎不起作用,希望这是由这些错误引起的。

【问题讨论】:

    标签: typescript


    【解决方案1】:

    模块和类可以在这些限制下合并:

    1. 模块必须类之后
    2. 它们必须在同一个文件中

    如果您查看代码生成,规则 #1 的原因就很明显了——在 JavaScript 中,您可以将属性添加到函数(在本例中为构造函数),但不能使用现有对象并将其转换为函数。

    #1 是 #2 的结果,因为对于并行编译,没有办法强制一个脚本在另一个之前加载,如果你的顺序错误,你会看到的行为将非常困难调试。

    【讨论】:

    • 感谢您的回答。我知道这些限制,我通过使用 --out 将所有文件编译为一个来处理它们。
    【解决方案2】:

    如果您的主要要求是使用较短的new Bar() 而不是new Foo.Bar(),那么最好的办法是将它们放在同一个模块中...如果我创建一个名为 Baz 的模块,我可以在第二个文件中扩展它并使用简写 new Bar() 而不是 new Baz.Bar();

    请记住,这将创建一个定向依赖 - Bar.ts 需要在 Foo.ts 之前加载

    Bar.ts

    module Baz {
        export class Bar {
            constructor() {
    
            }
        }
    }
    

    Foo.ts

    module Baz {
        class Foo {
            constructor() {
                var x = new Bar();
            }
        }
    }
    

    但是,如果您的主要要求是能够创建 new Foo()new Foo.Bar()可以使用模块扩展类...但您必须致电new Foo.Bar() - 你不能使用缩短的new Bar()

    class Foo {
        private x;
        constructor() {
             this.x = new Foo.Bar();
        }
    
        test() {
            return 'ftest+' + this.x.test();
        }
    }
    
    module Foo {
        export class Bar {
            constructor() {
    
            }
    
            test() {
                return 'btest';
            }
        }
    }
    
    var f = new Foo();
    var b = new Foo.Bar();
    
    alert(f.test()); // ftest+btest
    alert(b.test()); // btest
    

    【讨论】:

    • 感谢您的回答。我不知道我的英语是否足以完全理解你在说什么,但我阅读了语言规范,当我看到When merging a class and an internal module, ... 时,我认为在所描述的情况下这应该不是问题。所以我现在想做的事情是不可能的?
    • 有可能——但您必须使用全名...让我添加一个示例...
    • 感谢您的澄清,我将不得不重新考虑我的架构。我只是假设这是声明合并中的一个错误。
    猜你喜欢
    • 2022-12-18
    • 2020-08-02
    • 2022-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-15
    • 2018-06-28
    • 1970-01-01
    相关资源
    最近更新 更多