TypeScript practice is essential to note (8) - decorator

  Decorator (the Decorator) may be declared in the class and its members above (e.g., attributes, methods, etc.) as they provide a labeling, separation of complex logic for additional logic or additionally, the form of the syntax @expression. expression is a function that will be called at run time, its parameters are decorated statement information. Suppose there is a @sealed decorator, it can be defined Sealed () function as follows.

function sealed(target) {
  //...
}

  There are two ways to open the decorator, first is to add --experimentalDecorators parameters when inputting a command, as shown below, wherein --target parameter can not be omitted, its value is "ES5".

tsc default.ts --target ES5 --experimentalDecorators

  The second attribute is added experimentalDecorators tsconfig.json profile, as shown below, the corresponding target property can not be omitted.

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

A class decorator

  Constructor for class decorator monitor, modify or replace the class and type as the only decorative device may receive its parameters. When the decorative returns undefined, the extension of the original constructor; and when the decorative value has returned, it will be used to cover the original constructor. The following example will pass prototype class constructor and decorators enclosing class, wherein the class @sealed declared before.

@sealed
class Person {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
}
function sealed(constructor: Function) {
  Object.seal(constructor);
  Object.seal(constructor.prototype);
}

  After a TypeScript compiled, it will generate a __decorated () function, and applied to the Person class, as shown below.

var Person = /** @class */ (function() {
  function Person(name) {
    this.name = name;
  }
  Person = __decorate([sealed], Person);
  return Person;
})();

  Note that the class decorator .d.ts not appear in the declaration file and an external class.

Second, the method decorators

  The method of decoration for class declaration before acting on the process attribute descriptor, than more than a class decorator overload limit. It receives three parameters, as listed below:

  (1) The static member is the class constructor, for example members of the object class is the prototype.

  Name (2) members, a string or a symbol.

  (3) a member of the attribute descriptor, when the output is below the ES5 version, this value will be undefined.

  When the method returns a decorative value, attribute descriptor overwrites the current method. The following is a simple example, the first parameter is a decorator Person.prototype method, the second is the "cover", call getName () method will be obtained "freedom", instead of the original "strick".

class Person {
  @cover
  getName(name) {
    return name;
  }
}
function cover(target: any, key: string, descriptor: PropertyDescriptor) {
  descriptor.value = function() {
    return "freedom";
  };
  return descriptor;
}
let person = new Person();
person.getName("strick");        //"freedom"

Third, the accessor decorator

  Accessor decorator declared before accessing the class properties, the role of the corresponding attribute descriptor, which is restricted to the same class decoration, while receiving the same three parameters and methods decorator. And also need to note that, TypeScript is not allowed while a member of decorative get and set accessor, can only be applied on the first accessor.

  In the following Person class, for example, defines an accessor property name, when accessed, will get "freedom", rather than the original "strick".

class Person {
  private _name: string;
  @access
  get name() {
    return this._name;
  }
  set name(name) {
    this._name = name;
  }
}
function access(target: any, key: string, descriptor: PropertyDescriptor) {
  descriptor.get = function() {
    return "freedom";
  };
  return descriptor;
}
let person = new Person();
person.name = "strick";
console.log(person.name);        //"freedom"

Fourth, the property decorator

  Attribute declarations before decorative properties, which limits access to the decorator is the same, but only takes two parameters, a third attribute descriptor parameter does not exist, and no return value. Still below the Person class, for example, define a name attribute and its value modified @property decorator.

class Person {
  @property
  name: string;
}
function property(target: any, key: string) {
  Object.defineProperty(target, key, {
    value: "freedom"
  });
}
let person = new Person();
person.name = "strick";
console.log(person.name);        //"freedom"

Five parameters decorator

  Decorator parameters before the parameter declaration, it does not return value, which is the same as the method of limiting decorators, and can receive three parameters, the third parameter represents a position in which the decorative parameter in the parameter list of the function (i.e. index). Here an example to demonstrate the usage parameters decorators, the method needs to work with decorators.

let params = [];
class Person {
  @func
  getName(@required name) {
    return name;
  }
}

  @Func the call getName () method, and its incoming values ​​params array, @ required for the modified parameter values ​​specified location, as shown below.

function func(target: any, key: string, descriptor: PropertyDescriptor) {
  const method = descriptor.value;
  descriptor.value = function () {
    return method.apply(this, params);
  };
  return descriptor;
}
function required(target: any, key: string, index: number) {
  params[index] = "freedom";
}

  When instantiated Person class, call getName () method, will be obtained "freedom".

let person = new Person();
person.getName("strick");        //"freedom"

Sixth, decoration factory

  Decorator plant is capable of receiving arbitrary function argument, the decorator used to wrap, it is easier to use, it can return to any of the above functions decorator. Next, a method of retrofitting decorators in Cover () function takes a string parameter type value, the method returns a decorator function as follows.

function cover(value: string) {
  return function(target: any, key: string, descriptor: PropertyDescriptor) {
    descriptor.value = function() {
      return value;
    };
    return descriptor;
  };
}

  When applied to the @cover class methods, need to pass a string, as follows.

class Person {
  @cover("freedom")
  getName(name) {
    return name;
  }
}

Seven decorative combination

  When a plurality of the same decoration is applied to a statement, a line may be written may be written in multiple lines, as shown below.

/ * ***** line ***** * / 
@first @second desc 
/ * ***** multiline ***** * / 
@first 
@second 
desc

  Evaluated the way these decorative function similar to the composite first performed from top to bottom decorators, as a function of the evaluation result and then, successively from the bottom call. E.g. factory defines two decorative function, as shown in the following code, a number is printed on the body and return function decorator.

function first() {
  console.log(1);
  return function(target: any, key: string, descriptor: PropertyDescriptor) {
    console.log(2);
  };
}
function second() {
  console.log(3);
  return function(target: any, key: string, descriptor: PropertyDescriptor) {
    console.log(4);
  };
}

  They have to declare the same methods in the class, as shown in the following code. The order of evaluation can be seen, print out 1 and 3, 2 and 4 and then printed out.

class Person {
  @first()
  @second()
  getName(name) {
    return name;
  }
}

 

Guess you like

Origin www.cnblogs.com/strick/p/11792566.html