【typescript】TS编写和使用装饰器之(五):参数装饰器

注:我看了好多天ts官方文档,也看了参数装饰器的示例,到现在也没有想出一个更好的方案,向大家展示参数装饰器的使用方法。因为参数装饰器只能用来监视一个方法的参数是否被传入。所以这篇文章,我就先把官网的案例抄写下来,等我以后想明白了别的方案,再来修改成自己的demo

先看介绍:
参数装饰器声明在一个参数声明之前(紧靠着参数声明)。 参数装饰器应用于类构造函数或方法声明。 参数装饰器不能用在声明文件(.d.ts),重载或其它外部上下文(比如 declare的类)里。

参数装饰器表达式会在运行时当作函数被调用,传入下列3个参数:

对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
成员的名字。
参数在函数参数列表中的索引。
注意  参数装饰器只能用来监视一个方法的参数是否被传入。

参数装饰器的返回值会被忽略。

下例定义了参数装饰器(@required)并应用于Greeter类方法的一个参数,代码示例:

import "reflect-metadata"
const requiredMetadataKey = Symbol("required")

function validate(target: any, propertyName: string, descriptor: TypedPropertyDescriptor<any>) {
    let method = 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 (method as any).apply(this, arguments);
    }
}

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);
}

class Greeter {
    greeting: string;

    constructor(message: string) {
        this.greeting = message;
    }

    @validate
    greet(@required name: string) {
        return "Hello " + name + ", " + this.greeting;
    }
}

let paramMan = new Greeter("Jack")
paramMan.greet("haha")
paramMan.greet() //报错 "Missing required argument."

@required装饰器添加了元数据实体把参数标记为必需的。 @validate装饰器把greet方法包裹在一个函数里在调用原先的函数前验证函数参数。

注意这里的:

paramMan.greet() //报错 "Missing required argument."

如果你把这段代码直接写在ts里编译,那么他是不会通过的,因为

greet(@required name: string)

的参数是必须的。

所以为了测试这个装饰器的作用,你必须先编译,然后使用生成的js文件去加上paramMan.greet()来测试。这个功能对于第三方插件的编写是很有用的。

注意:这个例子使用了reflect-metadata库。 搜索元数据了解reflect-metadata库的更多信息。

好了,关于ts装饰器的介绍,到这里基本就结束了,后续会继续更新ts的其他相关内容,欢迎关注。

上一篇:TS编写和使用装饰器之(四):属性装饰器
下一篇:vue3在setup的render渲染函数中如何使用slots(插槽)

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值