zoukankan      html  css  js  c++  java
  • 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);
  • 相关阅读:
    CDH 2、Cloudera Manager的安装
    204 01 Android 零基础入门 03 Java常用工具类 04 Java集合 04 Map集合 01 Map概述
    203 01 Android 零基础入门 03 Java常用工具类 04 Java集合 03 Set集合 07 删除宠物猫信息数据(引入泛型知识点)
    202 01 Android 零基础入门 03 Java常用工具类 04 Java集合 03 Set集合 06 查找宠物猫信息数据
    201 01 Android 零基础入门 03 Java常用工具类 04 Java集合 03 Set集合 05 添加重复的宠物猫信息数据
    200 01 Android 零基础入门 03 Java常用工具类 04 Java集合 03 Set集合 04 添加和显式宠物猫信息
    199 01 Android 零基础入门 03 Java常用工具类 04 Java集合 03 Set集合 03 宠物猫信息管理概述
    198 01 Android 零基础入门 03 Java常用工具类 04 Java集合 03 Set集合 02 案例:在集合中插入字符串
    197 01 Android 零基础入门 03 Java常用工具类 04 Java集合 03 Set集合 01 Set概述
    196 01 Android 零基础入门 03 Java常用工具类 04 Java集合 02 List集合 05 案例:公告的删除和修改
  • 原文地址:https://www.cnblogs.com/KruceCoder/p/10564248.html
Copyright © 2011-2022 走看看