TypeScript 装饰器

TypeScript 装饰器

装饰器是一种特殊的声明,可以应用于类、方法、存取器、属性或参数。装饰器只是函数,其前缀是 @expression 符号,其中 expression 必须评估为在运行时将使用关于装饰声明的信息调用的函数。

注意:装饰器是一个实验性功能,提议用于 ES7。一些 JavaScript 框架,包括 Angular 2,已经在使用装饰器。装饰器可能会在未来版本中更改。

为了启用对装饰器的实验性支持,我们必须在 命令行tsconfig.json 中启用 experimentalDecorators 编译选项:

命令行

$tsc --target ES5 --experimentalDecorators

tsconfig.json

{
    "compilerOptions": {
        "target": "ES5",
        "experimentalDecorators": true
    }
}

目的

TypeScript装饰器的目的是以声明性的方式向现有代码添加注释和元数据。

装饰器工厂

为了自定义装饰器应用到声明的方式,我们可以编写一个装饰器工厂。装饰器工厂是一个返回表达式的函数,该表达式在运行时由装饰器调用。

装饰器工厂可以以以下方式编写:

function color(value: string) { // this is the decorator factory
    return function (target) { // this is the decorator
        // do something with 'target' and 'value'...
    }
}

装饰器组合

我们可以将多个装饰器应用于一个声明上。以下示例有助于理解。

在单行上

@f @g x

分行显示

@f
@g
x

装饰器的类型

TypeScript使用以下类型的装饰器:

TypeScript 装饰器

  1. 类装饰器
  2. 方法装饰器
  3. 访问器装饰器
  4. 属性装饰器
  5. 参数装饰器

1. 类装饰器

类装饰器定义在类声明之前,它描述了类的行为。类装饰器应用于类的构造函数。类装饰器可用于观察、修改或替换类定义。如果类装饰器返回一个值,它将用给定的构造函数替换类声明。

示例:

@sealed
class Person {
    msg: string;
    constructor(message: string) {
        this.msg = message;
    }
    show() {
        return "Hello, " + this.msg;
    }
}

在上面的示例中,当执行 @sealed 装饰器时,它将封闭构造函数和其原型,这样我们就无法继承 Person 类。

2. 方法装饰器

方法装饰器是在方法声明之前定义的。它应用于方法的属性描述符。它可以用于观察、修改或替换方法定义。我们不能在声明文件中使用方法装饰器。

方法装饰器函数的表达式接受三个参数。它们分别是:

  1. 类的构造函数(静态成员)或类的原型(实例成员)。
  2. 成员名称。
  3. 成员的属性描述符。

示例:

在下面的示例中, @log 装饰器将记录新的项目条目。

class Item {
    itemArr: Array;
    constructor() {
        this.itemArr = [];
        }
    @log
    Add(item: string): void {
       this.itemArr.push(item);
       }
    GetAll(): Array {
       return this.itemArr;
       }
}

3. 存取器装饰器

存取器装饰器是在存取器声明之前定义的。它应用于存取器的属性描述符。它可以用于观察、修改或替换存取器的定义。

注意:存取器是类声明的getter和setter属性。

存取器装饰器函数的表达式接受三个参数。它们是:

  1. 静态成员的类的构造函数,或实例成员的类的原型。
  2. 成员名称。
  3. 成员的属性描述符。

示例:

在下面的示例中,一个存取器装饰器 (@configurable) 被应用于 Employee 类的一个成员。

class Employee {
    private _salary: number;
    private _name: string;

    @configurable(false)
    get salary() { return 'Rs. {this._salary}'; }
    set salary(salary: any) { this._salary = +salary; }

    @configurable(true)
    get name() { return 'Sir/Madam,{this._name}'; }
    set name(name: string) { this._name = name; }
}

4. 属性装饰器

属性装饰器是在属性声明之前定义的。它类似于方法装饰器。属性装饰器和方法装饰器之间唯一的区别是,它们不接受属性描述符作为参数,也不返回任何内容。

属性装饰器函数的表达式接受两个参数。它们是:

  1. 静态成员的类构造函数,或实例成员的类的原型。
  2. 成员名称。

示例:

在下面的示例中,@ReadOnly装饰器将使name属性变为只读,因此我们无法更改其值。

class Company {
 @ReadOnly 
 name: string = "JavaTpoint.com";
}
let comp = new Company();
comp.name = 'SSSIT.com'; // Here, we can't change company name.
console.log(comp.name); // 'JavaTpoint.com'

5. 参数装饰器

参数装饰器是在参数声明之前定义的。它应用于类构造函数或方法声明的函数。它不能用在声明文件或任何其他环境上下文中(比如已声明的类)。

参数装饰器函数的表达式接受三个参数,它们分别是:

  1. 静态成员的类的构造函数或实例成员的类的原型。
  2. 成员名称。
  3. 参数在函数参数列表中的索引。

示例:

在下面的示例中,一个参数装饰器 (@required) 应用于 Person 类的成员参数。

class Person {
    msg: string;
    constructor(message: string) {
        this.msg = message;
    }
    @validate
    show(@required name: string) {
        return "Hello " + name + ", " + this.msg;
    }
}

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程