Typescript decorators 如何在 類別/屬性/方法 上標註資訊
Typescript decorators 如何在 類別/屬性/方法 上標註資訊
裝飾器(Decorators)為我們在類的聲明和成員上通過元編程語法添加標註提供 了一種方式,其實就是Java 中的annotation,只是 Decorators 除了標示還有更多功能,像是AOP…
定義Decorators
- 請先安裝
npm i reflect-metadata
- 先定義兩個 Decorators 如下 一個是類別(Clazz)用的,和屬性(Prop)用的
const metadataPropKey = 'PropInfo';
const metadataClazzKey = 'ClazzInfo';
// tslint:disable-next-line: typedef
export function Clazz(value: ClazzArgs) {
return (target: any) => {
Reflect.defineMetadata(metadataClazzKey, value, target);
};
}
// tslint:disable-next-line: typedef
export function Prop(value: PropArgs) {
return (target: any, propertyKey: string) => {
Reflect.defineMetadata(metadataPropKey, value, target, propertyKey);
};
}
// Class標註的參數
export interface ClazzArgs {
title: string;
}
// properties標註的參數
export interface PropArgs {
title: string;
type: string;
}
類別和屬性的差別是參數的不同來決定的
Reflect.defineMetadata(metadataClazzKey, value, target);
Reflect.defineMetadata(metadataPropKey, value, target, propertyKey);
npm i reflect-metadata
const metadataPropKey = 'PropInfo';
const metadataClazzKey = 'ClazzInfo';
// tslint:disable-next-line: typedef
export function Clazz(value: ClazzArgs) {
return (target: any) => {
Reflect.defineMetadata(metadataClazzKey, value, target);
};
}
// tslint:disable-next-line: typedef
export function Prop(value: PropArgs) {
return (target: any, propertyKey: string) => {
Reflect.defineMetadata(metadataPropKey, value, target, propertyKey);
};
}
// Class標註的參數
export interface ClazzArgs {
title: string;
}
// properties標註的參數
export interface PropArgs {
title: string;
type: string;
}
類別和屬性的差別是參數的不同來決定的
Reflect.defineMetadata(metadataClazzKey, value, target);
Reflect.defineMetadata(metadataPropKey, value, target, propertyKey);
在執行中(Runtime)取用該 decorators 的參數
開發取用標註的方法
public getPropArg(obj: any, field: string): PropArgs {
const o = Reflect.getMetadata(metadataPropKey, obj, field);
return o;
}
public getClazzArgs(obj: any): ClazzArgs {
return Reflect.getMetadata(metadataClazzKey, obj.constructor);
}
範例
定義簡單的有標註的類型
@Clazz({
title: 'Flow'
})
export class Flow {
@Prop({
title: 'name',
type: 'Text'
})
public name='abc';
public vars = new Map<string,string>();
@PropInfo({
title: 'entry',
type: 'Object'
})
public entry: new Map<string,string>();
}
執行
const f = new Flow();
const fClazzArgs = getClazzArgs(f);
console.log(fClazzArgs.title);
const fields = Object.keys(f);
for(const field of fields){
const fa = getPropArg(f,field);
if(fa){
console.log(`${fa.title} ${fa.type}`);
}
}
運行結果
Flow
name Text
entry Object
md code:
留言
張貼留言