[英]TypeScript Decorators and Circular Dependencies
考慮一下使用修飾符的相互依賴的代碼示例(如下)。
現在考慮以下工作流程(是的,我確實想傳遞實際的導出類,因為以后需要使用它們):
Parent.ts
@Test(Child)
使應用程序在裝飾時導入Child.ts
Parent
類 Child.ts
,執行@Test(Parent)
裝飾器 Parent
是未定義的,無法傳遞給裝飾器。 如您所見,有一個令人討厭的循環依賴,並且我看不到能夠應用將類作為彼此引用的參數的裝飾器的方法。
請注意,為簡便起見,我以@Test
為例。 實際的裝飾器是@HasMany
和@BelongsTo
所以我在這里有一個實際的用例。
我對您的問題: “是否有解決此問題的方法?”
我擔心的是,除非TypeScript的編譯代碼被更改以將修飾過程推遲到所有相關代碼都被導入之前,否則沒有。
Decorators.ts
:
export function Test(passedClass: Function): Function {
return function (model: Function): void {
console.log(typeof passedClass);
};
}
Parent.ts
:
import {Child} from "./Child";
import {Test} from "./Decorators";
@Test(Child)
export class Parent {
}
Child.ts
:
import {Parent} from "./Parent";
import {Test} from "./Decorators";
@Test(Parent)
export class Child {
}
今天遇到同樣的問題。 我通過將@Test(() => Parent)
替換為@Test(Parent)
來解決問題。
我沒有跟蹤元數據中的類構造函數( Parent
),而是跟蹤返回構造函數( () => Parent
)的thunk。 這將延遲對Parent
導入變量的求值,直到調用thunk為止,從而達到目的。
如果可以推遲在裝飾器中執行的操作-您可以克服此限制並打破循環依賴關系。 從真正的裝飾器的名稱@HasMany和@BelongsTo看來,您正在將某種元數據附加到每個類中供以后使用-如果是這樣,這是我的建議:
export function Test(passedClass: Function | string)
我在這里假設裝飾器會將元信息存儲在某種靜態字典中,例如:。 屬性看起來像哪里
{
hasMany: {new(): any} | string
belongsTo: {new(): any} | string
}
在裝飾器內部,將hasMany / belongsTo屬性設置為passedClass
以創建新的屬性對象。 如果passedClass
不是字符串,請檢查所有已添加的屬性,並替換所有字符串類型且當前等於passedClass.name
hasMany / passedClass.name
從父級刪除對子級的引用。
這是有點天真的實現,您可以實現一些私有字段,而不是隱藏中間字符串數據,並避免暴露聯合類型字段。
希望這會幫助你。
怎么做,但是結構不同呢?
如果Child
和Parent
都駐留在同一個文件中,那應該沒有問題。
這聽起來可能不是最佳的,因為由於長度和邏輯的原因,很容易將代碼分離為模塊,但這可以通過某種方式解決。
您可以擁有一個包含這些基本類(甚至是抽象類)的主文件:
// Base.ts
import {Test} from "./Decorators";
@Test(BaseChild)
export abstract class BaseParent {}
@Test(BaseParent)
export abstract class BaseChild {}
然后在您的特定模塊中:
// Parent.ts
import {BaseParent} from "./Base";
export class Parent extends BaseParent {}
和
// Child.ts
import {BaseChild} from "./Base";
export class Child extends BaseChild {}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.