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

TypeScript:如何在名称空间中使用内部接口,typescript,module,namespaces,Typescript,Module,Namespaces,我有一个接口,我只想在名称空间(内部模块)中使用,不应该在名称空间之外使用 示例界面: namespace Test { interface IInterface { getId(): number; getName(): string; } } namespace Test { class Implementer implements IInterface { private location: Location;

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

示例界面:

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";
        }
    }
}
namespace Test {
    class Location {
        private name: string = null;
        constructor(name: string) {
            this.name = name;
        }
    }
}
不幸的是,如果我不导出接口(我不想导出),当我尝试在同一名称空间中实现该接口时,我会遇到一个错误

实现类:

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";
        }
    }
}
namespace Test {
    class Location {
        private name: string = null;
        constructor(name: string) {
            this.name = name;
        }
    }
}
其中给出:TS2304:找不到名称“IInterface”。在“Implementer.ts”中

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

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

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";
        }
    }
}
namespace Test {
    class Location {
        private name: string = null;
        constructor(name: string) {
            this.name = name;
        }
    }
}
另外:我没有使用任何模块,我正在将一些类型从JavaScript转换为TypeScript类。使用
//
帮助程序不起作用(这里也不是问题)。我也不想介绍任何模块加载器


那么,我如何在不导出接口的情况下在同一名称空间中使用接口呢?

我首先回答最后一个问题:“如果在名称空间之外使用,则名称冲突的类”。浏览器中已存在。您可以在模块或命名空间中为类使用此名称。否则,您将不得不选择另一个名称

然后,您需要拆分一个名称空间。只需导出成员
i界面
,将其暴露在生命之外:

namespace Test {
    export interface IInterface {
        getId(): number;
        getName(): string;
    }
}
解释 发件人:

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

下面是一个示例(请参见代码):

编译完成后,下面是JavaScript代码:

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

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

名称空间
Test
是“全局名称空间中简单命名的JavaScript对象”。您可以观察到变量
message
无法在其IILife之外重用。即使我们为同一个全局变量(命名空间)创建了第三个IIFE <代码>测试< /代码>。

可能相关:另一个问题没有提到内部接口或在名称步或模块中的接口的可访问性,但是如果你开始一个新的项目,也许你应该考虑切换到模块。这只是一个建议。:)第一次导出将使接口在命名空间或模块之外可访问,因此这是不需要的。不应该通过重命名我自己的对象来处理已经存在的名称问题。名称空间和模块主要用来解决这个问题。@Huupke,我补充了一个解释。