TypeScript 5 進階:新版裝飾器入門

前言
TypeScript 5 裝飾器有重大的更新,這是因為裝飾器在 JavaScript 中首次提出於 ES2016 的草案中,並逐步經過 TC39 的標準化過程,最終在 TC39 Stage 3 中穩定下來,並在 TypeScript 5 中得到了實現。這使得裝飾器不再僅僅是一個實驗性特性,在未來也會是基於 JavaScript 標準的語法。
裝飾器的演進不僅讓 TypeScript 開發者能夠更加一致地撰寫裝飾器,還提高了裝飾器的靈活性與可讀性。這一篇將探討新版裝飾器與舊版的差異,並介紹新版裝飾器的使用方法和特性。
新舊版的差異
在 TypeScript 5 之前,裝飾器被視為實驗性功能,需要透過 experimentalDecorators 來啟用,並且是基於 TypeScript 自己的實現。如果要使用新版的裝飾器,experimentalDecorators 的設定就要關閉。
而新版裝飾器也提供了一些新的種類可以使用,這部分我們下一篇文章在說明,同時也不再支援舊版的參數裝飾器(Parameter Decorator)。
使用方式也與舊版的方式一樣,有差別的地方是,舊版傳的參數與新版傳的參數不一樣。
舊版的型別定義比較簡單

新版的型別定義的更加豐富且好用

可以到 node_modules/typescript/lib/lib.decorators.d.ts 查看。
新版裝飾器參數
新版裝飾器函式會提供兩個參數,分別為 target(被裝飾類別的建構子)與 context(執行的上下文)。

可以看到 context 有提供更多上下文資訊可以做使用,同時 TypeScript 也有定義各裝飾器種類的上下文型別,這邊就先用最通用的裝飾器上下文型別 DecoratorContext 來說明。
addInitializer:類別在定義完成後執行的回調函式kind:這個裝飾器的種類metadata:元資料name:套用裝飾器的類別名稱
而不同種類的裝飾器,還會支援不同的上下文方法,等到實作時在做介紹。
類別裝飾器
我們繼續用之前使用的範例,新版的類別裝飾器,除了 baseClass 這個參數外,還有 context 上下文這個參數,同時可以看到我們有使用 ClassDecoratorContext<T> 來進行裝飾器的約束,這樣就可以避免別人把這個裝飾器套用到類別以外的地方。
@withAge
class Person {
name: string = '阿毛'
}
function withAge<T extends new (...args: any) => {}>(
baseClass: T,
context: ClassDecoratorContext<T>
) {
console.log('套用年齡類別裝飾器')
context.addInitializer(() => {
console.log(`Class ${context.name} 的 addInitializer 執行`)
})
return class extends baseClass {
age: number = 18
constructor(...args: any[]) {
super(...args)
console.log(`套用年齡到 ${baseClass.name} 類別`)
}
}
}
const person1 = new Person()
const person2 = new Person()執行順序
可以看到我們在裝飾器內使用了 context 提供的方法,並觀察他的執行順序,可以發現 addInitializer 的執行時機是在類別在定義完成後執行的,可以利用這個特性做更多事情。
套用年齡類別裝飾器
Person Class 的 addInitializer 執行
套用年齡到 Person 類別
套用年齡到 Person 類別總結
本文介紹了新版 TypeScript 5 的裝飾器,並比較了新舊版裝飾器的主要差異。在下一篇文章中,我們將更深入探討如何利用其他種類的新版裝飾器。
參考資料
Related Posts
TypeScript 後記
終於完成連續三十天的鐵人賽文章撰寫!距離我第一次參加鐵人賽已經三年之久了。這次參加主要是因為朋友邀請一起參賽,同時我自己也想藉此機會深入了解 TypeScript 5 的新功能,強迫自己透過寫作來吸收知識。
TypeScript 實戰:製作 npm Package
在開發專案時,經常會遇到跨專案共用邏輯或工具的情況,例如常用的 logger 或驗證工具。如果每次都從一個專案複製貼上到另一個專案,難免會出現版本不同步或維護困難的問題。為了解決這類問題,我們可以將這些共用邏輯獨立成為 npm 套件,以便在多個專案中重複使用。
TypeScript 實戰:前端表單與串接 API
在現代前端開發中,與後端進行資料交換是常見的需求。透過 HTTP 請求,我們可以將資料送出並取得結果。這篇文章將介紹如何使用 TypeScript 實作前端表單與串接 API,並展示如何將這些功能結合到 React 應用中。同時,文章還會介紹如何解決跨域問題(CORS),以便讓前後端能順利溝通。
Johnson Mao
A passionate software engineer and blogger sharing thoughts on technology, AI, and development.