![](data:image/bmp;base64,Qk0uBAAAAAAAADYAAAAoAAAAEAAAABAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAUVM2/1RVNP9bWy7/ZGIl/2xpHf9wbhz/cXAl/25wMv9obT//YWlK/1llUf9VYlb/VWFW/1hiVf9cZFL/YGVP/1JTOf9VVjf/XVwx/2ZkKf9uayH/c3Af/3RyJ/9xcjP/a29A/2RsSv9daFL/WWVX/1hkWf9bZVj/X2ZW/2NoVP9WVkH/WVg//2FfOv9rZzL/c28q/3l1J/97eCv/eHg2/3N2Qf9tck3/Zm9V/2JsXP9ha1//Y2xg/2ZtYP9pb2D/XFlL/19cSv9nY0T/cWw9/3p0Nf+AezH/g38y/4KAOv9+f0X/eHxQ/3J5Wv9udmL/bHVn/211a/9vdm3/cXdu/2BcVv9kX1T/bGdQ/3ZwSP+AeUD/h4E7/4uGOv+LiED/iYhJ/4SGVf9/g1//eoBp/3d/cP92fnX/dn55/3d+e/9kX2D/Z2Je/29pWv95c1L/g3xK/4uFRP+Ri0L/ko5G/5GQT/+Oj1r/iY1l/4SKb/+Ah3j/fYV+/3uDgv96goX/ZmJp/2lkZ/9wa2L/enNb/4R9U/+Mhkz/k41K/5eTTf+XllX/lpZg/5KVa/+MkXX/ho19/4CIhP97hIj/d4GL/2Zjbv9oZW3/bmpo/3dyYf+Be1n/ioVT/5KNUP+XlFP/mplb/5qbZf+Xmm//kZZ5/4mQgf+AiYf/d4KL/3F8jf9lZHL/Z2Vw/2tpa/9yb2X/e3dd/4SBV/+NilX/lJNY/5mZX/+bnGj/mJxy/5KYev+IkIH/fIaG/3B8iv9mdIz/ZGRy/2Rlcf9nZ2z/bWtm/3RyX/99e1r/hoZZ/4+PW/+VlmL/mJtq/5abcv+Qlnn/hY1//3eCg/9ndYb/WmqH/2Nkb/9jZG7/ZGVq/2hoZf9tbl//dXZb/36AWv+HiV3/jpFi/5GWaf+QlnD/ipF2/3+Ie/9wfH7/X22A/1Bigf9jZGr/Y2Rp/2NkZv9lZmH/aWtd/29yWv93eln/f4Nc/4WKYP+Ijmb/h45s/4KKcf94gXX/anV3/1poef9MXXn/ZWRi/2RkYf9kZF//ZWZc/2dqWf9rb1f/cHVX/3Z8Wf97gV3/fYRh/3yEZv94gGr/cHlt/2VvcP9aZXH/UF1y/2dkWP9nZFj/Z2VX/2dnVv9oalX/am5U/2xyVP9vdlX/cHhX/3F5Wv9weF7/bXZi/2hxZf9ja2n/XWZr/1lhbf9qZE7/amVP/2pnT/9ralD/a2xQ/2tvUf9qcFH/aXFR/2dwUv9mb1T/ZG1W/2NrWv9ial7/Ymlj/2JoZv9iZ2n/bGRH/2xlR/9taEn/bmtL/25uTf9scE7/aW9O/2ZuTv9ha07/XWdO/1tlUP9bZFT/XmVZ/2JnX/8=)
TypeScript@5のDecoratorを動かしてみる
publication: 2023/01/31
update:2024/02/20
TypeScript5 と TC39/Stage3 への対応状態
検証バージョン
typescript@5.0.0-betaでの検証です。
検証に使用したテストプログラムは以下の場所に置いてあります。
https://github.com/SoraKumo001/typescript-decorator
使える Decorator 一覧
ClassDecorator
ClassMethodDecorator
ClassGetterDecorator
ClassSetterDecorator
ClassFieldDecorator
ClassAccessorDecorator
Parameter 関連の Decorator はありません。
DecoratorContext の access プロパティは pending になっています。
動作確認
テストプログラム
typescript@5.0.0-betaで動作するようにテストプログラムを書きました。
Decorator には標準対応しているので、tsconfig.jsonは標準のままで動作します。
1type AnyFunction = (...args: any[]) => any;23type S3ClassDecorator = (4 value: Function,5 context: ClassDecoratorContext6) => void | (new () => any);78type ClassMethodDecorator = (9 value: Function,10 context:11 | ClassMethodDecoratorContext12 | ClassGetterDecoratorContext13 | ClassSetterDecoratorContext14) => void | AnyFunction;1516type ClassFieldDecorator = (17 value: undefined,18 context: ClassFieldDecoratorContext19) => (initialValue: unknown) => any | void;2021type ClassAccessorDecorator = (22 value: ClassAccessorDecoratorTarget<unknown, unknown>,23 context: ClassAccessorDecoratorContext24) => ClassAccessorDecoratorResult<unknown, any>;2526const classDecorator: S3ClassDecorator = (value, context) => {27 context.addInitializer(() =>28 console.log(`初期化:${context.kind}:${String(context.name)}`)29 );30 console.log(value, context);31};3233const classFieldDecorator: ClassFieldDecorator = (value, context) => {34 console.log(value, context);35 return (initialValue) =>36 `取得:${context.kind}:${String(context.name)} => ${initialValue}`;37};3839const classMethodDecorator: ClassMethodDecorator = (value, context) => {40 console.log(value, context);41 context.addInitializer(() =>42 console.log(`初期化:${context.kind}:${String(context.name)}`)43 );44 return function (this: unknown, ...args: any[]) {45 return `取得:${context.kind}:${String(context.name)} => ${value.apply(46 this,47 args48 )}`;49 };50};5152const classAccessorDecorator: ClassAccessorDecorator = (value, context) => {53 console.log(value, context);54 return {55 get(this) {56 return `取得:${context.kind}:${String(context.name)} => ${value.get.apply(57 this58 )}`;59 },60 };61};6263console.log("START");6465@classDecorator66class Test1 {67 @classAccessorDecorator68 a = 1;69 @classFieldDecorator70 b = 10;71 @classMethodDecorator72 get c() {73 return 123;74 }75 @classMethodDecorator76 add(a: number, b: number) {77 return a + b;78 }79}8081console.log("test1");82const test = new Test1();83console.log(test.a);84console.log(test.b);85console.log(test.c);86console.log(test.add(10, 20));8788console.log("test2");89const test2 = new Test1();90console.log(test2.a);91console.log(test2.b);92console.log(test2.c);93console.log(test2.add(10, 20));9495console.log("END");
出力結果
1START2{ get: [Function: get a], set: [Function: set a] } {3 kind: 'accessor',4 name: 'a',5 static: false,6 private: false,7 addInitializer: [Function (anonymous)]8}9[Function: get c] {10 kind: 'getter',11 name: 'c',12 static: false,13 private: false,14 addInitializer: [Function (anonymous)]15}16[Function: add] {17 kind: 'method',18 name: 'add',19 static: false,20 private: false,21 addInitializer: [Function (anonymous)]22}23undefined {24 kind: 'field',25 name: 'b',26 static: false,27 private: false,28 addInitializer: [Function (anonymous)]29}30[class Test1] {31 kind: 'class',32 name: 'Test1',33 addInitializer: [Function (anonymous)]34}35初期化:class:Test136test137初期化:getter:c38初期化:method:add39取得:accessor:a => 140取得:field:b => 1041取得:getter:c => 12342取得:method:add => 3043test244初期化:getter:c45初期化:method:add46取得:accessor:a => 147取得:field:b => 1048取得:getter:c => 12349取得:method:add => 3050END
まとめ
legacy の Decorator と比べると完全に構造が変わっており、古いプログラムをこちらに対応させようとすると、それなりに書き換えが必要です。また ParameterDecorator が現時点で存在していないので、それに依存したプログラムだと移植は難しいでしょう。なかなか使いどころが難しい感じになってしまいました。