【问题标题】:Duplicate identifier error with d.ts file and nodejs require with same named.ts 文件和 nodejs 需要具有相同名称的重复标识符错误
【发布时间】:2014-08-12 00:09:47
【问题描述】:

现在我确定问题是因为其中包含一个 d.ts 文件,其中包含一个名为“Shared”的模块,以及一个包含同名变量(如果在 NodeJS 环境中使用)的 require 语句。

// shared.d.ts
declare module Shared { ... }

// other_module.ts
/// <reference path="shared.d.ts"/>
if(require) { var Shared = require("shared"); }
export class Something {
    public someVar = new Shared.SomethingElse("blah");
}

所以当我编译other_module.ts(实际上是很多单独的文件)时,它告诉我 Shared 是一个重复的标识符,我可以理解为 TS 认为 Shared 是一个模块,但随后被告知它是要求返回。

这里的问题是模块的输出需要与nodeJS的require系统兼容,所以在这种情况下,当需要other_module时,它将在自己的范围内并且不会知道Shared.SomethingElse所以需要require所以other_module 中的内部模块将能够访问共享库,但在浏览器环境中它将通过全局范围获得 Shared.SomethingElse

如果我删除引用,则文件将无法编译,因为它不知道 Shared,如果我在将模块加载到 nodejs (var otherModule = require("other_module")) 时删除 require,它会抱怨它不知道关于Shared。那么有没有办法解决这个问题呢?

【问题讨论】:

    标签: javascript node.js typescript tsc


    【解决方案1】:

    首先是错误

    重复标识符,因为您在 shared.d.ts 中有 Shared + 在 other_module.ts 中。

    FIX A,都是外部的

    如果你想使用amd / commonjs 即。 外部模块,你需要使用import/require(而不是像你正在做的var/require)。使用import 会创建一个新变量声明空间,因此您不再会从other_module.ts 污染全局命名空间Shared。简而言之:

    // shared.d.ts
    declare module Shared { 
       export function SomethingElse(arg:string):any;
    }
    declare module 'shared'{ 
        export = Shared; 
    }
    

    还有一个类型安全的导入:

    // other_module.ts
    
    /// <reference path="shared.d.ts"/>
    import Shared = require("shared"); 
    
    export class Something {
        public someVar = new Shared.SomethingElse("blah");
    }
    

    FIX B,和你一样,但你需要使用不同的名称

    other_module 内部,如果本地范围是全局范围,则不要在本地使用名称Shared。我建议您在任何地方都使用 external 并使用 commonjs 编译节点,使用 amd 编译浏览器,如修复 A 所示,但如果您必须在这里编译修复 other_module.ts

    // other_module.ts
    /// <reference path="shared.d.ts"/>
    var fooShared: typeof Shared;
    if(require) {  fooShared = require("shared"); }
    else { fooShared = Shared; } 
    export class Something {
        public someVar = new fooShared.SomethingElse("blah");
    }
    

    【讨论】:

    • 问题是我需要污染全局命名空间以便在浏览器中使用,该场景基本上是在服务器和客户端之间共享的 Web 服务上的数据契约。所以我只想要一组可以在两边使用的类。因此,我尝试以某种方式编写它,如果需要等可用,它就会使用它,否则它只依赖于全局变量。如果我要使用导入路线下去,我需要在浏览器中使用模块加载器,但情况并非如此。还要使用import Shared 我需要在共享库中使用export module,但它是很多文件。
    • 啊!您的 B 示例似乎可行,将尝试并报告 +1 的想法。
    • 似乎有效,所以这至少应该让我克服困难,感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2011-01-27
    • 2012-08-23
    • 2021-09-15
    • 2011-10-19
    • 1970-01-01
    • 1970-01-01
    • 2022-06-14
    • 2016-01-04
    相关资源
    最近更新 更多