• TypeScript 装饰器


    1. 类装饰器

    应用于类构造函数,
    *****参数是类的构造函数

    function Path(path: string){
        
        return function(target: Function){
            !target.prototype.$Meta && (target.prototype.$Meta = {})
            
            target.prototype.$Meta.baseUrl = path;
        };
    }
    
    @Path("/hello")
    class HelloService{
        constructor()
    }
    
    console.log(HelloService.prototype.$Meta);// 输出:{ baseUrl: '/hello' }
    
    let hello = new HelloService();
    
    console.log(hello.$Meta) // 输出:{ baseUrl: '/hello' }

    2. 方法装饰器

    参数为:
    1)对于静态成员来说是类的构造函数,对于实例成员来说是类的原型对象
    2)成员的名字
    3)成员的属性描述符

    function GET(url: string) {
        return function (target, methodName: string, descriptor: PropertyDescriptor) {
            //tartget: 静态类来说是构造函数
            //methodName: 方法名
            //descriptor:方法对应的属性描述符 其对应的value就是方法体
        }
    }
    
    
    class HelloService{
        constructor(){}
        
        @GET("xx")
        static getUser(){}
    }
    
    console.log((<any>HelloService).$Meta);

    3. 访问器装饰器
    参数为:
    1)对于静态成员来说是类的构造函数,对于实例成员来说是类的原型对象
    2)成员的名字
    3)成员的属性描述符

    class Point {
        private _x: number;
        private _y: number;
        constructor(x: number, y: number) {
            this._x = x;
            this._y = y;
        }
    
        @configurable(false)
        get x() { return this._x; }
    
        @configurable(false)
        get y() { return this._y; }
    }
    
    function configurable(value: boolean) {
        return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
            descriptor.configurable = value;
        };
    }

    4. 属性装饰器

    参数列表
    1)对于静态成员来说是类的构造函数,对于实例成员是类的源性对象
    2)成员的名字

    class Greeter {
        @format("Hello, %s")
        greeting: string;
    
        constructor(message: string) {
            this.greeting = message;
        }
        greet() {
            let formatString = getFormat(this, "greeting");
            return formatString.replace("%s", this.greeting);
        }
    }
    
    import "reflect-metadata";
    
    const formatMetadataKey = Symbol("format");
    
    function format(formatString: string) {
        return Reflect.metadata(formatMetadataKey, formatString);
    }
    
    function getFormat(target: any, propertyKey: string) {
        return Reflect.getMetadata(formatMetadataKey, target, propertyKey);
    }

    5. 参数装饰器

    参数列表:
    1)对于静态成员来说是类的构造函数,对于实例成员是类的源性对象
    2)成员的名字
    3)参数在函数参数列表中的索引

    class Greeter {
        greeting: string;
    
        constructor(message: string) {
            this.greeting = message;
        }
    
        @validate
        greet(@required name: string) {
            return "Hello " + name + ", " + this.greeting;
        }
    }
    
    import "reflect-metadata";
    
    const requiredMetadataKey = Symbol("required");
    
    function required(target: Object, propertyKey: string | symbol, parameterIndex: number) {
        let existingRequiredParameters: number[] = Reflect.getOwnMetadata(requiredMetadataKey, target, propertyKey) || [];
        existingRequiredParameters.push(parameterIndex);
        Reflect.defineMetadata(requiredMetadataKey, existingRequiredParameters, target, propertyKey);
    }
    
    function validate(target: any, propertyName: string, descriptor: TypedPropertyDescriptor<Function>) {
        let originalMethod = descriptor.value;
        descriptor.value = function () {
            let requiredParameters: number[] = Reflect.getOwnMetadata(requiredMetadataKey, target, propertyName);
            if (requiredParameters) {
                for (let parameterIndex of requiredParameters) {
                    if (parameterIndex >= arguments.length || arguments[parameterIndex] === undefined) {
                        throw new Error("Missing required argument.");
                    }
                }
            }
    
            return originalMethod.apply(this, arguments);
        }
    }

     举个例子:

    const CheckNullKey = Symbol();
    const Router = Symbol();
    
    function CheckNull(target: any, name: string, index: number) {
        target[Router] = target[Router] || {};
        target[Router][name] = target[Router][name] || {};
        target[Router][name].params = target[Router][name].params || [];
        target[Router][name].params[index] = CheckNullKey;
    }
    
    function Check(target: any, name: string, descriptor: PropertyDescriptor) {
        let method = descriptor.value;
        descriptor.value = function() {
            let params = target[Router][name].params;
            if (params) {
                for (let index = 0; index < params.length; index++) {
                    if (params[index] == CheckNullKey
                        && (arguments[index] === undefined || arguments[index] === null)) {
                        throw new Error("Missing required arguments");
                    }
                }
            }
            return method.apply(this, arguments);
        }
    }
    
    class Controller {
    
        @Check
        public getContent( @CheckNull id: string): string {
            console.info(id);
            return id;
        }
    }
    
    new Controller().getContent(null);
  • 相关阅读:
    最小化程序到托盘
    Delphi
    c# 多线程
    下载地址加密
    一个很让我郁闷的java异常
    XmlBeanFactory和ApplicationContext读取spring xml配置文件
    tomcat部署war出错的问题
    JAXB 实现List接口
    Mongo数据模型
    JAXB, Web Services, and Binary Data
  • 原文地址:https://www.cnblogs.com/KruceCoder/p/10564248.html
Copyright © 2020-2023  润新知