2017-03-31 124 views
1

鑑於打字稿中的特定設置,我最終在運行時使用了javascript中的空類對象。設置僅僅是相互引用的兩個類將等於其中一個在另一個的範圍內是空的。我知道如何避免它(通過在2之間引入第三個類),但我很好奇它爲什麼會發生,並且還有一種方法仍然可以交叉引用並仍然有一個工作代碼。我嘗試了很多設置,試圖使其工作,所以這就是我發現的。打字稿類成爲空

設置:自己的模塊中的每個類(模塊名稱和類名無關) ClassA的是我們主要的條目:

// ClassA的

import ClassB = require('ClassB'); 
import ClassC = require('ClassC'); 

class ClassA 
{ 
    constructor() 
    { 
     console.log(ClassC.TEST);// shows 1 
     new ClassB();// shows null 
     console.log(ClassC.TEST);// shows 1 
    } 
} 
export = ClassA; 

// ClassB的(不同的模塊中)

import ClassC = require('ClassC'); 

class ClassB 
{ 
    public static ClassBRef:any; 

    constructor() 
    { 
     console.log(ClassC.TEST);// in this scope ClassC is an empty object with no properties 
    } 
} 
export = ClassB; 

// ClassC(在不同的模塊)

import ClassB = require('ClassB'); 

class ClassC 
{ 
    public static TEST:number = 1; 

    constructor() 
    { 
     ClassB.ClassBRef; 
    } 
} 
export = ClassC; 

因爲ClassB引用了ClassC和ClassC引用ClassB,所以這裏的結果是:ClassA範圍內的ClassC存在沒有問題,但在ClassB範圍內,ClassC是運行時沒有屬性的空對象。換句話說,在打字稿中一切都很好,但JavaScript不會。在構造函數或實例方法或靜態方法等中使用靜態或實例作用域來更改模塊名稱,位置,類名,這些都沒有什麼區別,並且ClassC在ClassB作用域中始終爲空。

就像我說的修復是有一個第三類處理與2個錯誤類的通信(所以至少2個類中的一個沒有引用第二個),但我的問題是,如何做到這一點沒有需要第三個類而不去除這兩個類之間的交叉引用?

回答

0

您在ClassBClassC之間有循環參考。在任何JavaScript環境中,解決這些問題真的很難。

基本上有兩種情況。

ClassBrequire d。 d。一個或兩個以上的數字。 ClassC嘗試requireClassB

在這種情況下,因爲ClassB仍在構建中(它沒有導出任何東西),所以它將是未定義的。如果首先加載ClassC,則會發生相反情況。

有一種方法可以解決它,沒有額外的文件,但它「感覺」錯了。

import containerC = require('ClassC'); 
// or import * as containerC from 'ClassC'; in ES6 syntax 

export class ClassB 
{ 
    public static ClassBRef:any; 

    constructor() 
    { 
     console.log(containerC.ClassC.TEST);// in this scope ClassC is an empty object with no properties 
    } 
} 

// ClassC 
import containerB = require('ClassB'); 

export class ClassC 
{ 
    public static TEST:number = 1; 

    constructor() 
    { 
     containerB.ClassB.ClassBRef; 
    } 
} 

這是可能的,因爲需要返回的值會被時間要麼類運行的constructor來填充。

您不能使用export = X語法,您必須使用命名的導出語法。在模塊加載之前,您也不能嘗試訪問任何一個類。所以它必須位於類被導出後調用的構造函數或函數中。

+0

THX的解釋,我想試試並回報。 –

+0

這兩個發佈的答案都很好,但這個有更多的解釋,爲什麼我的設置失敗。公認。另一個問題是爲什麼打字機編譯器認爲該設置沒有問題。另外,因爲我的打字稿項目是自動生成的(來自另一種語言),我將保留第三類橋接解決方案,因爲它最適合轉換後的代碼。 Thx –

0

使用語法 import { ClassC } from "./ClassC";導入,而不是import ClassC = require('ClassC');

B類的類,:

import { ClassC } from "./ClassC"; // use this syntax 

class ClassB 
{ 
    public static ClassBRef:any; 

    constructor() 
    { 
     console.log(ClassC.TEST); 
    } 
} 
export { ClassB }; 

C類:

import { ClassB } from "./ClassB"; // use this syntax 

class ClassC 
{ 
    public static TEST:number = 1; 

    constructor() 
    { 
     ClassB.ClassBRef; 
    } 
} 

export { ClassC }; 
+0

我也會嘗試,並回報。 –

+0

也注意到了輸出模塊的語法。它是'export {ClassC}'而不是'export = ClassC'。 –