在Angular项目中,我使用TypeLITE为来自后端的对象自动生成一堆接口。那部分效果很好,我对物体有智能感知,并且(在某种程度上)那些类型安全。
但现在我遇到了包含枚举的第一个类,TypeLITE正确地拾取并在enums.ts中创建TypeScript代码。这两个文件的内容如下所示:
classes.d.ts
declare namespace My.Multi.Level.Namespace {
interface MyInterface {
Status: My.Multi.Level.Namespace.Status;
}
}
enums.ts
namespace My.Multi.Level.Namespace {
export const enum Status {
Undefined = 0,
New = 1,
...
}
}
someOtherFile.ts
// How/what to import to access this?
const status = My.Multi.Level.Namespace.New;
引用该枚举的“classes.d.ts”中的实际接口仍然可以正常工作。
但现在我尝试导入该命名空间以在运行时访问“Status”枚举,并且无法弄清楚如何执行此操作。无论我做什么,命名空间都不可用。
我尝试将其更改为“export namespace ...”甚至“export module ...”但这会破坏“classes.d.ts”中生成的代码。我需要一个解决方案,允许我在运行时使用枚举,并保持与类完整的连接。
我理解在模块和命名空间方面存在一些不兼容性,但我只是假设有一些方法来解决它并实际使用这些枚举?
USED VERSION
Angular 4.3.6
TypeScript 2.3.4.
编辑:简化示例
如果您想在自己的机器上尝试我遇到的问题,请按以下步骤操作:
1)创建一个新的最小角度应用
ng new enumtest --minimal
2)使用以下代码修改app.component.ts
文件:
import { Component, OnInit } from '@angular/core';
import { My } from './classes';
@Component({
selector: 'app-root',
template: `<p>{{myEnum}}</p>`
})
export class AppComponent implements OnInit {
myEnum: My.Multi.Level.Namespace.Status;
ngOnInit() {
console.log("ngOnInit:begin:myEnum");
this.myEnum = My.Multi.Level.Namespace.Status.New;
console.log("ngOnInit:after:myEnum");
}
}
3)添加此文件classes.ts
// classes part
namespace My.Multi.Level.Namespace {
export interface MyInterface {
Title: string;
Status: My.Multi.Level.Namespace.Status;
}
}
namespace My.Other.Multi.Level.Namespace {
export interface SomeInterface {
Context: My.Multi.Level.Namespace.MyInterface[];
}
}
// enums part
namespace My.Multi.Level.Namespace {
export const enum Status {
Undefined = 0,
New = 1
}
}
export import My = My;
预期的行为:页面上将显示“1”(枚举的值)并且它仍然会编译,因为所有引用仍然完好无损(如My.Other.Multi.Level.Namespace.SomeInterface.Context仍然连接到My .Multi.Level.Namespace.MyInterface [])。
答案 0 :(得分:1)
正如@Aleksey L.提到你需要export
命名空间,它将适用于一个文件,但问题是每当你在顶层导出时,Typescript开始假设该文件是一个模块(并有充分理由)。
Namespace
是为了模仿假设在全局上的文件中的模块行为。
你几乎没有选择:
实际上,在我的工作中,我们曾经大量使用过命名空间(当我们的所有代码库都在全局声明时),然后每当我们在构建系统中引入Webpack时,我们就开始将代码转换为使用 ES6模块,其中一个步骤是删除命名空间。
我们要求逐步进行转换,因此部分代码使用了namespaces
和一些ES6 modules
。
为了保持向后兼容性,我们保留了包含命名空间的文件,并为每个文件创建了一个新文件,该文件从全局读取命名空间并将其导出到内部。
类似的东西:
// old-file.ts
namespace someName {
export class SomeClass {
}
}
//old-file.es6.ts
export import SomeClass = someName.SomeClass;
希望有所帮助。