美文网首页
TS 装饰器(2): 元数据

TS 装饰器(2): 元数据

作者: 菜鸡前端 | 来源:发表于2022-02-27 02:39 被阅读0次

TS 装饰器(2): 元数据

装饰器函数中 ,我们可以拿到类、方法、访问符、属性、参数的基本信息,如它们的名称,描述符等。获取更多信息就需要通过另外的方式来进行:元数据

1、什么是元数据?

元数据:用来描述数据的数据,在我们的程序中,对象、类等都是数据,它们描述了某种数据。另外还有一种数据,它可以用来描述 对象、类,这些用来描述数据的数据就是元数据

在编译过程中产生的元数据是非常重要的信息,比如在 nestjs 框架中 DI 和 IOC 的实现久依赖了他们。

2、reflect-metadata

首先,需要安装 reflect-metadata

2.1、定义元数据

我们可以给类、方法 等数据定义元数据,元数据会被附加到指定的 类、方法等数据之上,但是又不会影响类、方法本身的代码。

2.2、使用语法

(1) 设置
Reflect.defineMetadata(metadataKey, metadataValue, target, propertyKey)

  • metadataKey:meta 数据的 key
  • metadataValue:meta 数据的 值
  • target:meta 数据附加的目标
  • propertyKey(可选):对应的 property key

(2) 获取
Reflect.getMetadata(metadataKey, target, propertyKey)

import "reflect-metadata";

class A {
  public static method1() {}
  public method2() {}
}

let obj = new A();

Reflect.defineMetadata("key", 1, A);
Reflect.defineMetadata("key", 2, A, "method1");
Reflect.defineMetadata("key", 3, obj);
Reflect.defineMetadata("key", 4, A, "method2");

console.log(Reflect.getMetadata("key", A));
console.log(Reflect.getMetadata("key", A, "method1"));
console.log(Reflect.getMetadata("key", obj));
console.log(Reflect.getMetadata("key", obj, "method2"));

2.3、装饰器简化操作

  • 通过 Reflect.defineMetadata 方法调用来添加元数据
  • 通过 @Reflect.metadata 装饰器来添加元数据
import "reflect-metadata";

@Reflect.metadata("key", 1)
class A {
  @Reflect.metadata("key", 2)
  public static method1() {}

  @Reflect.metadata("key", 4)
  public method2() {}
}

let obj = new A();

console.log(Reflect.getMetadata("key", A));
console.log(Reflect.getMetadata("key", A, "method1"));
console.log(Reflect.getMetadata("key", obj));
console.log(Reflect.getMetadata("key", obj, "method2"));

3、使用 emitDecoratorMetadata

如何知道一个方法中有多少个参数,每个参数的类型是什么呢?tsconfig.json 中有一个配置 emitDecoratorMetadata,开启该特性,typescript 会在编译之后自动给类、方法、访问符、属性、参数添加如下几个元数据:

  • design:type:被装饰目标的类型
    • 装饰器作用于成员属性:属性的标注类型
    • 装饰器作用于成员方法:Function 类型
  • design:paramtypes: 被装饰目标的参数类型
    • 装饰器作用于成员方法:方法形参列表的标注类型
    • 装饰器作用于类:构造函数形参列表的标注类型
  • design:returntype
    • 成员方法:函数返回值的标注类型

3.1、方法装饰器实验

源码:

function f() {
  return function (target: any, name: string, descriptor: PropertyDescriptor) {
    console.log(descriptor.value.length);
  };
}

class B {
  name: string;
  constructor(a: string) {
    this.name = a;
  }
  @f()
  method(a: string, b: string): string {
    return "a";
  }
}

产物:

// 太长了,隐藏实现
var __decorate = function () {}

var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};

function f() {
    return function (target, name, descriptor) {
        console.log(descriptor.value.length);
    };
}
var B = /** @class */ (function () {
    function B(a) {
        this.name = a;
    }
    B.prototype.method = function (a, b) {
        return "a";
    };
    __decorate([
        f(),
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [String, String]),
        __metadata("design:returntype", String)
    ], B.prototype, "method", null);
    return B;
}());

3.2、类装饰器实验

@testable
class MyTestableClass {
  constructor (name: string, age: number) {}
}

function testable(target: Function) {
  (target as any).isTestable = true;
}

(MyTestableClass as any).isTestable // true

产物:

var MyTestableClass = /** @class */ (function () {
    function MyTestableClass(name, age) {
    }
    MyTestableClass = __decorate([
        testable,
        __metadata("design:paramtypes", [String, Number])
    ], MyTestableClass);
    return MyTestableClass;
}());
function testable(target) {
    target.isTestable = true;
}
MyTestableClass.isTestable; // true

相关文章

  • TS 装饰器(2): 元数据

    TS 装饰器(2): 元数据 在装饰器函数中 ,我们可以拿到类、方法、访问符、属性、参数的基本信息,如它们的名称,...

  • TypeScript装饰器与原型链

    TypeScript中的装饰器&元数据反射:从新手到专家IITypeScript中的装饰器&元数据反射:从新手到专...

  • 装饰器实验

    装饰器实验 说明 ts内包含了四个装饰器,类装饰器、属性装饰器、函数装饰器、参数装饰器,本文中测试一下其的使用。 ...

  • TS装饰器

    装饰器是一种特殊类型的声明,本质上就是一个方法,可以注入到类、方法、属性、参数上,扩展其功能; 常见的装饰器:类装...

  • TS装饰器

    装饰器是一种特殊类型的声明,可以被附加到类生命、方法、访问符、属性或参数上,可以修改类的行为。使用@express...

  • ts装饰器

    1、装饰器是什么?装饰器是一种特殊类型的声明,他能够附加到类声明、属性、方法、参数上,可以修改类的行为。通俗的讲,...

  • TS装饰器

    一:类的装饰器:是一种与类(class)相关的语法,用来注释或修改类和类方法,装饰器本身是一个函数,装饰器通过@来...

  • 从零开发ts装饰器管理koa路由

    前言 两年前刚学ts,当时搭了个简单的koa的demo,介绍了如何用装饰器管理koa的路由:TS装饰器初体验,用装...

  • TS 装饰器(1): 基础用法

    TS 装饰器(1): 基础用法 1、什么是装饰器 装饰器是通过添加标注的方式,来对类型进行扩展的一种方式。 只能在...

  • 装饰器和元数据

    1.装饰器: 装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰...

网友评论

      本文标题:TS 装饰器(2): 元数据

      本文链接:https://www.haomeiwen.com/subject/yuncrrtx.html