装饰器在 TS 中是一个实验性的特性,需要在tsconfig.json中将 experimentalDecorators 设置为true来禁止警告。
那什么是装饰器呢?按照Learning Typescript中的说法就是
A class decorator is just a function that takes the class as its only argument and returns it after doing something with it
说白了意思就是,装饰器就是一个函数,然后在使用时候会将被装饰的类作为参数传递到函数内,然后你就可以想干啥干啥了。
直接上代码:
function addMetadata(target: any) {
target.__customMetadata = {
somekey: "value",
};
return target;
}
@addMetadata
class Person {
private _name: string;
public constructor(name: string) {
this._name = name;
}
public greet() {
return this._name;
}
}
function getMetadataFromInstance(target: any) {
return target.constructor.__customMetadata;
}
let person1 = new Person("John");
let person2 = new Person("Lisa");
console.log(getMetadataFromInstance(person1)); // { somekey: 'value' }
console.log(getMetadataFromInstance(person2)); // { somekey: 'value' }
需要注意的一点是 在声明类时应用装饰器,而不是在创建类的实例时应用。这意味着元数据在类的所有实例中共享:
let person1 = new Person("John");
let person2 = new Person("Lisa");
console.log(getMetadataFromInstance(person1) === getMetadataFromInstance(person2)); // true
如何给装饰器传参数?
我们可以在装饰器函数中返回一个匿名函数来实现,具体代码如下
function addMetadata(max: number) {
return function (target: any) {
target._random = Math.floor(Math.random() * max);
};
}
@addMetadata(10)
class Person {
private _name: string;
public constructor(name: string) {
this._name = name;
}
public greet() {
return this._name;
}
}
function getMetadataFromClass(target: any) {
return target.constructor._random;
}
const person = new Person("随机数");
console.log(getMetadataFromClass(person)) // 6