TypeScript:如何在命名空间内使用内部接口

时间:2016-10-07 12:51:55

标签: typescript module namespaces

我有一个我只想在命名空间(内部模块)中使用的接口,它不应该在命名空间之外使用。

示例界面:

namespace Test {
    interface IInterface {
        getId(): number;
        getName(): string;
    }
}

不幸的是,当我尝试在同一名称空间中实现此接口时,如果我不导出接口(我不想这样做),则会出现错误。

实施课程:

namespace Test {
    class Implementer implements IInterface {
        private location: Location;

        public getId(): number {
            return 1;
        }

        public getName(): string {
            return "implementer name";
        }
    }
}

给出: TS2304:在'Implementer.ts'中找不到名称'IInterface'。

请注意“Location”类型的私有成员,它也是我自己在同一名称空间中定义的新类型/类,这是使用名称空间的实际原因,因为“Location”类型已存在于全局空间中。 / p>

如果在命名空间外使用,则名称冲突的类:

namespace Test {
    class Location {
        private name: string = null;
        constructor(name: string) {
            this.name = name;
        }
    }
}

此外:我没有使用任何模块,我正在将一些类型从JavaScript转换为TypeScript类。使用/// <reference path="IInterface.ts" />帮助程序不起作用(这里不是问题)。我也不想介绍任何模块加载器。

那么如何在不导出的情况下在相同的命名空间中使用我的界面呢?

1 个答案:

答案 0 :(得分:2)

我首先回答最后一个问题:&#34;如果在名称空间外使用,则#34;具有冲突名称的类#34;。浏览器中已存在global object Location。您可以在模块或命名空间中为您的类使用此名称。否则,您必须选择其他名称。

然后,您要分割命名空间。只需export成员IInterface,以便将其暴露在IIFE之外:

namespace Test {
    export interface IInterface {
        getId(): number;
        getName(): string;
    }
}

解释

来自the handbook

  

命名空间只是全局命名空间中的JavaScript对象。

以下是插图(请参阅代码in the TS Playground):

namespace Test {
  export let name = 'abc'
}

namespace Test {
  let message = 'Hello, ' + name;
}

编译之后,这里是JavaScript代码:

var Test;
(function (Test) {
    Test.name = 'abc';
})(Test || (Test = {}));

var Test;
(function (Test) {
    var message = 'Hello, ' + Test.name;
})(Test || (Test = {}));

命名空间Test是一个&#34;简称为全局命名空间中的JavaScript对象&#34; 。您可以观察到变量message无法在其IIFE之外重用。即使我们为同一个全局变量(命名空间)Test创建第三个IIFE。