2017-10-18 53 views
2

在Angular项目中,我使用TypeLITE为来自后端的对象自动生成一堆接口。这部分运作良好,我对物体具有智能感知,并且对某些物体(某种程度上)具有类型安全性。从TypeLITE在Angular项目中生成的多级别名称空间导入TypeScript enum

但是现在我遇到了包含枚举的第一个类,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”中的实际接口仍然正常工作。

但现在我尝试导入该名称空间以在运行时访问“状态”枚举,并且无法弄清楚如何执行该操作。无论我做什么,命名空间都不可用。

我试着将它改为“导出命名空间...”或者甚至是“导出模块...”,但是会破坏在“classes.d.ts”中生成的代码。我需要一个解决方案,它允许我在运行时使用enum以及完整地保留类的连接。

我知道在模块和命名空间中存在一些不兼容性,但我只是假设有一些方法可以解决它并实际使用这些枚举?

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

缺少的部分是'namespace'之前的'export'。那么你可以'从我的导入{我}}“..' –

+0

我很确定我尝试过,但我认为这不起作用,因为多级命名空间?无论如何,明天再试一次,谢谢! – Marc

+0

啊,现在我记住,虽然添加“导出”将解决无法导入枚举(可以正常导出)的问题,但它会打破使用此枚举的“classes.d.ts”的链接(编译器显示为“classes.d.ts (40,53):命名空间'My.Multi.Level.Namespace'没有导出成员'MyEnum'。“) – Marc

回答

1

As @Aleksey L.提到你需要export这个命名空间,它可以用于一个文件,但问题是,无论何时你在顶级输出时,Typescript都会认为该文件是一个模块(并且是一个很好的理由)。

Namespace在打字稿被发明,以模拟在假设是对全球文件模块行为。

您有几种选择:

  1. 如果你并不需要在全局命名空间,你可以摆脱它,并且直接从每个文件导出枚举/接口。
  2. 如果确实需要,应导出的命名空间和它的所有内容假设在同一个文件写入,所以枚举&接口将在同一个文件

其实,在我的工作我们曾经大量使用过命名空间(当我们在全局声明所有的代码库时),然后每当我们在构建系统中引入Webpack时,我们开始将代码转换为使用ES6模块,其中一个步骤是删除命名空间。

我们有一个要求逐渐完成这个转换,所以一些代码使用namespaces和一些ES6 modules。 为了保持向后兼容性,我们保留了包含命名空间的文件,并为每个文件创建了一个新文件,该文件从全局读取命名空间并导出它的内部。

类似的东西:

// old-file.ts 
namespace someName { 
    export class SomeClass { 

    } 
} 

//old-file.es6.ts 
export import SomeClass = someName.SomeClass; 

希望有所帮助。

+0

感谢您的回复。不幸的是,这也行不通,也许我在这里错过了一些东西。我无法改变命名空间,因为这些命名空间是来自大型项目,删除或重命名它们根本无法实现。我试着把你的建议放到一个文件中(所以我不再使用.d声明)和导出导入,但枚举在运行时仍然不可用。将用另一个简化的例子更新我的问题。 – Marc

相关问题