前言
在 TypeScript – Decorator 裝飾器 裏,我有提到 TypeScript 只實現了 decorate 的特性,把 metadata 的特性獨立了出來。
本來我以爲還需要等待很長的時間他們纔會實現,沒想到 v5.2 既然推出了。哎喲,不錯哦!
聲明: Decorator 不是 TypeScript 語法,它是 ECMAScript (AKA JavaScript) 標準。Metadata 也是,目前是 stage 3。
參考
Docs – Announcing TypeScript 5.2
什麼是 Decorator Metadata?
Decorator Metadata 類似於 C# 的 Attribute。就是在 class 屬性上寫標籤(簡單說就是記入一些資料)。然後通過反射獲取到這些資料並且使用它們。
通常我們用它來實現 Metaprogramming。
搭建環境
和上一篇的 Disposable 做法類似。
必須使用 TypeScript Compiler (AKA tsc),esbuild 還不支持 Decorator。
tsconfig.json 加上 compilerOptions.lib "ESNext.Decorators"
{ "compilerOptions": { "target": "ES2017", "lib": [ "ES2017", "ESNext.Decorators", "DOM" ], } }
再加上 runtime polyfill
(Symbol as { metadata: symbol }).metadata ??= Symbol("Symbol.metadata");
使用方式
定義 decorator function
function setMetadata(_target: unknown, context: ClassMemberDecoratorContext) { context.metadata[context.name] = true; }
metadata 這個屬性是新的。之前的 Decorator 沒有。
apply to class member
class Person { @setMetadata firstName = 'Derrick'; }
反射
console.log(JSON.stringify(Person[Symbol.metadata])); // {"firstName":true}
簡單明瞭。
實戰場景
TODO future... 等以後有用上了,再補。