2017-10-18 56 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

相關問題