原文:
https://www.logicbig.com/tutorials/misc/typescript/class-decorators.html
https://medium.com/iqoqo-engineering/understand-typescript-decorators-in-5-minutes-26ffc6189082
————————————————————————————————————————————————————————
TypeScript - Class Decorators[Last Updated: Feb 28, 2019]
|
|
What are decorators?A Decorator is a special kind of declaration that can be attached to a class declaration, method, accessor, property, or parameter. Decorators use the form @expression, where expression must evaluate to a function that will be called at runtime with information about the decorated declaration. Decorators are a stage 2 proposal for JavaScript. That means decorators will be part of JavaScript in a future release. To enable decorators, we must enable the experimentalDecorators compiler option either on the command line or in your tsconfig.json. Class decoratorsThis tutorial shows the use of Class decorators. If a decorator expression has the arguments e.g. @expression("a", 3) then these arguments are passed to the decorator function expression(arg1: string, arg2: number). If a decorator expression has no arguments e.g. @expression then the constructor function of the class is passed to the decorator function expression(theConstructor: Function) In both above cases the decorator expression can return a new constructor function to replace or override the original constructor function. Examplestsconfig.json{
"compilerOptions": {
"target": "ES6",
"experimentalDecorators": true
}
}
In the presence of the above file, we simply need to run tsc to compile all .ts files to .js files in the same directory. A Basic Decorator - adding new propertiesIn following example, the decorator SelfDriving adds a new property to the target class. Ex1ClassDecorator.tsfunction SelfDriving(constructorFunction: Function) {
console.log('-- decorator function invoked --');
constructorFunction.prototype.selfDrivable = true;
}
@SelfDriving
class Car {
private _make: string;
constructor(make: string) {
console.log('-- this constructor invoked --');
this._make = make;
}
}
console.log('-- creating an instance --');
let car: Car = new Car("Nissan");
console.log(car);
console.log(`selfDriving: ${car['selfDrivable']}`);
console.log('-- creating one more instance --');
car = new Car("Toyota");
console.log(car);
console.log(`selfDriving: ${car['selfDrivable']}`);
Output-- decorator function invoked --
As seen above the decorator function is called only once when the class Car definition is loaded (before any instance is created). The compiled JavaScriptvar __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
function SelfDriving(constructorFunction) {
console.log('-- decorator function invoked --');
constructorFunction.prototype.selfDrivable = true;
}
var Car = /** @class */ |