什么是元数据

简单的说就是对数据的额外的描述,例如:

  1. const obj = {
  2. name: '哈哈哈'
  3. }

元数据就是对name进行额外的描述。

环境配置

默认情况下TypeScript是不支持元数据的。需要进行额外的配置。

通过下面的命令来安装一个第三方的包:

  1. npm install reflect-metadata
  2. # 或者
  3. yarn add reflect-metadata

使用

下面是具体的一个示例,需要注意的是,需要先引入第三方的包:

  1. import 'reflect-metadata';
  2. // 为数据设置元数据
  3. const userdata = {
  4. username: 'root',
  5. };
  6. // 设置元数据
  7. // Reflect.defineMetadata()方法参数,
  8. // 参数1: 描述信息的key
  9. // 参数2: 描述信息
  10. // 参数3: 操作的对象
  11. // 参数4: 针对的key
  12. Reflect.defineMetadata(
  13. 'haha',
  14. { url: 'http://www.baidu.com' },
  15. userdata,
  16. 'username'
  17. );
  18. // 读取属性的描述
  19. console.log(Reflect.getMetadata('haha', userdata, 'username')); // { url: 'http://www.baidu.com' }

使用元数据来验证方法的参数

示例代码如下:

  1. import 'reflect-metadata';
  2. // 使用参数装饰器 来进行数据验证
  3. // 设置装饰器 -- 分别设置参数装饰器和 方法装饰器
  4. const MethodDecorator: MethodDecorator = (
  5. target: object,
  6. propertyKey: string | symbol,
  7. descriptor: PropertyDescriptor
  8. ) => {
  9. console.log('方法装饰器');
  10. // 当方法装饰器执行的时候,获取内容
  11. // console.log(Reflect.getMetadata('required', target, propertyKey));
  12. // 将原来的方法函数保存起来
  13. const method = descriptor.value;
  14. // 重新定义装饰器绑定的方法
  15. // 装饰器绑定的方法中传递的参数都会传入重新定义的函数中,可以通过arguments查询
  16. descriptor.value = function () {
  17. // 获取用来修饰的元数据,如果没有使用参数装饰器,则默认值为一个空的数组
  18. const requiredParams: number[] =
  19. Reflect.getMetadata('required', target, propertyKey) || [];
  20. requiredParams.forEach((index) => {
  21. // index 表示要操作的数据的索引
  22. // console.log('@@',index)
  23. if (index > arguments.length || arguments[index] === undefined) {
  24. // 如果传入的参数错误,则直接抛出一个错误
  25. throw new Error('请传入必要的参数');
  26. }
  27. });
  28. return method.apply(this, arguments);
  29. };
  30. };
  31. const ValidateDecorator: ParameterDecorator = (
  32. target: Object,
  33. propertyKey: string | symbol,
  34. parameterIndex: number
  35. ) => {
  36. console.log('参数装饰器');
  37. // 将需要验证的参数压入到数组当中
  38. let requiredParams: number[] = [];
  39. requiredParams.push(parameterIndex);
  40. // 使用元数据将数组当做需要验证的参数的修饰
  41. Reflect.defineMetadata('required', requiredParams, target, propertyKey);
  42. };
  43. // 创建一个类
  44. class User {
  45. @MethodDecorator
  46. find(name: string, @ValidateDecorator id: number) {
  47. console.log(id);
  48. }
  49. }
  50. new User().find('root', 100);