banner
banner
banner
NEWS LETTER

TS-装饰器

Scroll down

目前装饰器是一项实验性特性,使用可以参照java

启用

  • 命令行:tsc –target ES5 –experimentalDecorators
  • 在tsconfig.json中的compilerOptions设置:
    1
    2
    3
    4
    5
    6
    {
    "compilerOptions": {
    "target": "ES5",
    "experimentalDecorators": true
    }
    }

概念

  • 装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,访问符,属性或参数上。
  • 装饰器使用 @expression这种形式,expression求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入。

装饰器工厂

1
2
3
const color = (value: string) =>{ //装饰器工厂
return (target) => {} //装饰器
}

装饰器组合

  • 书写同一行或多行都可:@f
  • 当多个装饰器应用于同一个声明上,从上到下,求值的结果从下到上
  • 示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    function f() {
    console.log("f(): evaluated")
    return function (target,propertyKey: string, descriptor: PropertyDescriptor) {
    console.log("f():called")
    }
    }

    function g() {
    console.log("g(): evaluated")
    return function (target,propertyKey: string, descriptor: PropertyDescriptor) {
    console.log("g():called")
    }
    }
    class C {
    @f
    @g
    method() {}
    }

    控制台:
    f(): evaluated
    g(): evaluated
    g():called
    f():called

装饰器求值

  1. 参数装饰器,然后依次是方法装饰器,访问符装饰器,或属性装饰器应用到每个实例成员。
  2. 参数装饰器,然后依次是方法装饰器,访问符装饰器,或属性装饰器应用到每个静态`成员
  3. 参数装饰器应用到构造函数。
  4. 类装饰器应用到类

类装饰器

  • 类装饰器在类声明之前被声明(紧靠着类声明)
  • 类装饰器应用于类构造函数,可以用来监视,修改或替换类定义。
  • 类装饰器不能用在声明文件中(.d.ts),也不能用在任何外部上下文中
  • 定义装饰器,在类中应用
  • 示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    @sealed
    class Greeter {
    greeting: string
    constructor(message: string) {
    this.greeting = message
    }
    greet() {
    return "Hello," + this.greeting
    }
    }

    function sealed(constructor: Function) {
    Object.seal(constructor)
    Object.seal(constructor.prototype)
    }

方法装饰器 和 访问器装饰器(/后面表示不同其他基本一致)

  • 声明在一个方法/访问器的声明之前(紧靠着方法/访问器声明)。
  • 会被应用到方法/访问器的属性描述符上,可以用来监视,修改或者替换方法/访问器定义。
  • 不能用在声明文件(.d.ts),重载或者任何外部上下文中
  • 运行时会当作函数被调用,传入3个参数:
    1. 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
    2. 成员的名字
    3. 成员的属性描述符
  • 返回一个值,它会被用作方法的属性描述符。

属性装饰器

  • 声明在一个属性声明之前(紧靠着属性声明)。
  • 不能用在声明文件中(.d.ts),或者任何外部上下文里
  • 运行时当作函数被调用,传入下列2个参数:
    1. 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
    2. 成员的名字

参数装饰器

  • 声明在一个参数声明之前(紧靠着参数声明)。
  • 应用于类构造函数或方法声明。
  • 不能用在声明文件中(.d.ts),或者任何外部上下文里
  • 运行时当作函数被调用,传入下列3个参数:
    1. 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
    2. 成员的名字
    3. 参数在函数参数列表中的索引
  • 只能用来监视一个方法的参数是否被传入,返回值会被忽略。

元数据

  • 安装: npm i reflect-metadata –save,
  • 启用:
    • 命令行:tsc –target ES5 –experimentalDecorators –emitDecoratorMetadata
    • 直配置
      1
      2
      3
      4
      5
      6
      7
      8
      tsconfig.json:
      {
      "compilerOptions": {
      "target": "ES5",
      "experimentalDecorators": true,
      "emitDecoratorMetadata": true
      }
      }

示例

1
2
3
4
5
6
7
8
9
10
11
12
const testDecorator = (xxx: xxx) => { // 创建一个装饰器, 如果有形参则@的表达式也要有形参
return (target: any) => { // target代表装饰的目标,等于例子的DecoratorTest
target.isTeatable =true; //target.xxx:往target原型上的constructor添加方法或属性
console.log(target);
}
}

@testDecorator() // 装饰器指定要装饰的目标
export default class DecoratorTest { // 被装饰的目标target
public name = ''
public age = 0
}
其他文章
cover
TS-JS文件类型检查
  • 24/11/01
  • 11:40
  • TypeScript
cover
TS-声明合并
  • 24/11/01
  • 11:40
  • TypeScript
目录导航 置顶
  1. 1. 启用
  2. 2. 概念
  3. 3. 装饰器工厂
  4. 4. 装饰器组合
  5. 5. 装饰器求值
  6. 6. 类装饰器
  7. 7. 方法装饰器 和 访问器装饰器(/后面表示不同其他基本一致)
  8. 8. 属性装饰器
  9. 9. 参数装饰器
  10. 10. 元数据
  11. 11. 示例
请输入关键词进行搜索