ts-decorator-reflect
TypeScript icon, indicating that this package has built-in type declarations

2.2.0 • Public • Published

装饰器构建 + 反射工具

更名为decorator-reflect decorator-reflect

用于创建装饰器工厂(带参数的装饰器、装饰器工厂、 这里叫这个工厂为'注解'), 合并现有的装饰器 ,并可以像java反射一样得到typescript中class信息(属性、方法、方法参数、以及它们的装饰器工厂(注解)和类型)

DecoratorBuilder build出来的是装饰器的工厂 无参时的使用方法 @Test() 或 @Test

安装

npm i ts-decorator-reflect -s

使用方法

基本使用方法

import {DecoratorBuilder, ReflectUtil} from "ts-decorator-reflect";

const TestAnnotation = DecoratorBuilder.create<string>()
    .class((target, option, paramTypes) => {
        console.log('**********class');
        console.log(target); // [Function: TestClass]
        console.log(option); // test class
        console.log(paramTypes); // [ [Function: Number], [Function: String] ]
    }).parameter((target, propertyKey, parameterIndex, option, type) => {
        console.log('**********parameter');
        console.log(target); // [Function: TestClass]
        console.log(propertyKey); // undefined
        console.log(parameterIndex); // 1
        console.log(option); // test parameter
        console.log(type); // [Function: String]
    }).property(((target, propertyKey, option, isStatic, type) => {
        console.log('**********property');
        console.log(target); // [Function: TestClass]
        console.log(propertyKey); // prop
        console.log(option); // test property
        console.log(isStatic); // true
        console.log(type); // [Function: Boolean]
    })).method(((target, propertyKey, descriptor,
                 option, isStatic, paramTypes, returnType) => {
        console.log('**********method');
        console.log(target); // TestClass {}
        console.log(propertyKey); // prop
        console.log(option); // test property
        console.log(isStatic); // false
        console.log(paramTypes); // [ [Function: String] ]
        console.log(returnType); // [Function: Boolean]
    })).build();

@TestAnnotation('test class')
class TestClass {

    @TestAnnotation('test property')
    static prop?: boolean;

    constructor(a: number, @TestAnnotation('test parameter') b: string) {
    }
    @TestAnnotation('test method')
    method(a: string): boolean {
        return true;
    }
}
// 获取反射信息
// console.log(ReflectUtil.getClassDefinition(TestClass));

合并多个已有装饰器

import {DecoratorBuilder, ReflectUtil} from "ts-decorator-reflect";
const Test: ClassDecorator = (target) => {
    // do something
}
const Test2: ClassDecorator = (target) => {
    // do something
}
const Test3: MethodDecorator = (target) => {
    // do something
}

const TestWrapper = DecoratorBuilder.create().class(Test).class(Test2).method(Test3).build();

@TestWrapper()
class TestClass {
    @TestWrapper()
    test() {}
}

console.log(ReflectUtil.getClassDefinition(TestClass));
// export type ClassDefinition<T extends Function> = {
//     name: string;
//     type: T;
//     annotations: AnnotationDefinition[];
//     properties: PropertyDefinition[];
//     methods: MethodDefinition[];
//     parameters: ParameterDefinition[];
// }

环境

  • node v12
  • reflect-metadata
  • typescript
  • ts-node@8.3.0

注意:有一些情况不会被反射出来

  • 属性没有装饰器(比如下面的TestDecorator类的属性 pro1 )
  • 方法 和 方法参数都没有装饰器(比如下面的TestDecorator类的方法 method4 )

最小项目例子

mkdir ts-decorator-reflect-test
cd ts-decorator-reflect-test

npm init

tsc --init

npm i ts-decorator-reflect reflect-metadata typescript ts-node@8.3.0

vim test.ts

test.ts

import {DecoratorBuilder, ReflectUtil} from "ts-decorator-reflect";

const TestDecorator = DecoratorBuilder.create<string>().class().method().parameter().property().build();

@TestDecorator('test class option')
export class Test {

    @TestDecorator('pro1 property option')
    private pro: string = '';

    constructor(@TestDecorator('constructor option') a: string) {}

    @TestDecorator('method1 option')
    method1(@TestDecorator('method1 param1 option') a: number): string {
        return '';
    }
    @TestDecorator('method2 option')
    method2(): void {
    }
    method3(@TestDecorator('method3 param1 option') a: number): number {
        return 0;
    }

    /*************没有装饰器的属性不会被反射,以上属性和方法会被反射,以下属性和方法不会被反射************/
    public pro1: string = '';
    method4(a: number): string {
        return '';
    }
}
const classDefinition = ReflectUtil.getClassDefinition(Test);
console.log(classDefinition);
/**
 * 结果
 {
  decorators: [ { type: [Function: TestDecorator], option: 'test class option' } ],
  methods: [
    {
      name: 'method1',
      decorators: [ { type: [Function: TestDecorator], option: 'method1 option' } ],
      returnType: [Function: String],
      parameters: [ { decorators: [ { type: [Function: TestDecorator], option: 'method1 param1 option' } ], type: [Function: Number] } ],
      isStatic: false
    },
    {
      name: 'method2',
      decorators: [ { type: [Function: TestDecorator], option: 'method2 option' } ],
      returnType: undefined,
      parameters: [],
      isStatic: false
    },
    {
      name: 'method3',
      decorators: [],
      returnType: [Function: Number],
      parameters: [ { decorators: [ { type: [Function: TestDecorator], option: 'method3 param1 option' } ], type: [Function: Number] } ],
      isStatic: false
    }
  ],
  properties: [
    {
      type: [Function: String],
      decorators: [ { type: [Function: TestDecorator], option: 'pro1 property option' } ],
      name: 'pro',
      isStatic: false
    }
  ],
  name: 'Test',
  type: [Function: Test],
  parameters: [ { decorators: [ { type: [Function: TestDecorator], option: 'constructor option' } ], type: [Function: String] } ]
}
 */

由于使用到decorator特性 tsconfig.json需要开启下面俩个选项

{
  "experimentalDecorators": true,
  "emitDecoratorMetadata": true
}

运行测试

ts-node test.ts

输出类的反射信息

{
  decorators: [ { type: [Function: TestDecorator], option: 'test class option' } ],
  methods: [
    {
      name: 'method1',
      decorators: [ { type: [Function: TestDecorator], option: 'method1 option' } ],
      returnType: [Function: String],
      parameters: [ { decorators: [ { type: [Function: TestDecorator], option: 'method1 param1 option' } ], type: [Function: Number] } ],
      isStatic: false
    },
    {
      name: 'method2',
      decorators: [ { type: [Function: TestDecorator], option: 'method2 option' } ],
      returnType: undefined,
      parameters: [],
      isStatic: false
    },
    {
      name: 'method3',
      decorators: [],
      returnType: [Function: Number],
      parameters: [ { decorators: [ { type: [Function: TestDecorator], option: 'method3 param1 option' } ], type: [Function: Number] } ],
      isStatic: false
    }
  ],
  properties: [
    {
      type: [Function: String],
      decorators: [ { type: [Function: TestDecorator], option: 'pro1 property option' } ],
      name: 'pro',
      isStatic: false
    }
  ],
  name: 'Test',
  type: [Function: Test],
  parameters: [ { decorators: [ { type: [Function: TestDecorator], option: 'constructor option' } ], type: [Function: String] } ]
}

Dependencies (0)

    Dev Dependencies (4)

    Package Sidebar

    Install

    npm i ts-decorator-reflect

    Weekly Downloads

    4

    Version

    2.2.0

    License

    ISC

    Unpacked Size

    236 kB

    Total Files

    156

    Last publish

    Collaborators

    • liangshen~