TypeScript 的 Decorator 小記
前言
前幾天在重構 Discord bot 時,碰上了相同的架構下需要人工 import
大量 module
的問題。既然在架構相同的情況下,能不能有效的降低人工重複的操作?這個想法不禁在我腦海中徘徊。後來剛好找到了 discordx 這個 repo,發現他們利用 decorator 來解決類似的問題,受到他們的啟發,我便開始自己嘗試撰寫 decorator 。
正文
前置作業
要開啟 TypeScript 的 decorator 功能,必須先在 tsconfig.json
中加入以下內容
1 | { |
或是在編譯時加上 --experimentalDecorators
參數。
TypeScript 中的 decorator
Decorator 是一種特殊的函式,可以用來修飾類別、方法、屬性等。在 TypeScript 中,共有以下幾種:
- Class Decorator
- Method Decorator
- Accessor Decorator
- Property Decorator
- Parameter Decorator
Decorator 會根據類型不同而有不同的參數。
Decorator Factories
由於 Decorator 函式的參數是綁死的,沒辦法變動,無法應付一般常態的需求,因此可以利用工廠函式來根據參數生成 Decorator。以官方文件的例子來說
1 | function color(value: string) { |
我們用工廠函式生成對應的 Decorator,這樣就可以利用自己的參數控制 Decorator 的行為了。
Decorator 的參數
關於各個 Decorator 的參數,這邊就不再多贅述了,可以直接參考官方文件,這個小章節只會對幾個參數的值做簡單解釋。
主要這次我有接觸的是 Method Decorator,所以下面就以 Method Decorator 為例。
這是 Method Decorator 的宣告
1 | function (target: any, propertyKey: string, descriptor: PropertyDescriptor); |
target
除了是物件的實體外,上頭還會帶有constructor
,propertyKey
是 method 的名稱,descriptor
是PropertyDescriptor
的物件,我們可以利用它來設定 property descriptor,不過實際上我並沒有使用過。
如果我們想讓別的程式經由 Decorator 的註冊來呼叫 method,要記得透過 target 還有 propertyKey 來呼叫。否則會因為失去物件的實體導致 this
之類的關鍵字失效。
具體來說會像下面這樣來呼叫函式
1 | target[propertyKey](...args); |
結語
今天是在深夜找事情做的時候寫紀錄,所以寫得很偷懶,內容不多,感謝不嫌棄還讀到最後的你。