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

2022-02-26  本文已影响0人  菜鸡前端

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

1、什么是装饰器

装饰器是通过添加标注的方式,来对类型进行扩展的一种方式。

2、装饰器语法

装饰器的使用非常简单,装饰器本质就是一个函数,在特定的位置调用装饰器函数即可对数据(类、方法、甚至参数等)进行扩展。下面例子演示给 MyTestableClass 类添加静态属性 isTestable:

@testable
class MyTestableClass {}

function testable(target) {
  target.isTestable = true;
}

MyTestableClass.isTestable // true

3、装饰器的分类

装饰器 是一个函数,它可以通过 @funName 在类、方法、访问符、属性、参数上,对它们进行包装,然后返回一个包装后的目标对象(类、方法 、访问符、属性、参数)。

3.1、类装饰器

类装饰器表达式会在运行时当作函数被调用,类的构造函数作为其唯一的参数。下面例子演示给 MyTestableClass 类添加静态属性 isTestable:

源代码:

@testable
class MyTestableClass {}

function testable(target) {
  target.isTestable = true;
}

MyTestableClass.isTestable // true
image

3.2、类方法装饰器

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

下面的例子演示让类的方法变为只读。

(1) 实例方法

function readonly(target, name, descriptor) {
    descriptor.writable = false;
    return descriptor;
}
class Cat {
    @readonly
    say() {
        console.log("meow ~");
    }
}
image

(2) 静态方法

class MyTestableClass {
    @testable
    static sleep() {}
}

function testable(target, name, descriptor) {
  target.isTestable = true;
}

MyTestableClass.isTestable // true

3.3、类属性装饰器

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

属性描述符不会做为参数传入属性装饰器,这与TypeScript是如何初始化属性装饰器的有关。官方文档有说明。

class MyTestableClass {
    @testable
    name: string;
    constructor(name: string) {
        this.name = name;
    }
}

function testable(target, name) {
  console.log(arguments)
}
image

3.4、参数装饰器

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

注意  参数装饰器只能用来监视一个方法的参数是否被传入。参数装饰器的返回值会被忽略。

class Greeter {
    greeting: string;

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

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

4、装饰器的执行顺序

  1. 实例装饰器:属性装饰 -> 访问器装饰 -> 参数装饰 => 方法装饰
  2. 静态装饰器: 属性 => 访问器 => 参数 => 方法
  3. 类装饰器

5、复合装饰器

@d1
@d2
class Greeter {
  greeting: string;
  constructor(message: string) {
    this.greeting = message;
  }

  greet() {
    return "Hello, " + this.greeting;
  }
}

function d1(target: Function) {}
function d2(target: Function) {}

6、装饰器工厂

如果我们需要给装饰器执行过程中传入一些参数的时候,就可以使用装饰器工厂来实现,它返回一个装饰器函数。

@Controller('user')
class Greeter {
  greeting: string;
  constructor(message: string) {
    this.greeting = message;
  }

  greet() {
    return "Hello, " + this.greeting;
  }
}

function Controller(path: string) {
  return function (target: Function) {
    (target as any).path = path;
  }
}
上一篇下一篇

猜你喜欢

热点阅读