type Ctor<T> = new (...args: any[]) => T
function auto<T>(className: Ctor<T>) {
return function (target: any, attr: any) {
// target 是类的原型对象, attr 属性的名称 (url)
console.log(target);
console.log(attr);
console.log(className)
target[attr] = new className();
}
}
function autoClass<T extends {
new(...args: any[]): any }>(constructor: T) {
return class extends constructor {
name = "new property";
age = "override";
}
}
class Name {
constructor() {
}
consoleMsg() {
console.log(22222)
}
}
@autoClass
class Greeter {
property = "property";
hello: string;
name: string
age: string
@auto(Name)
newProperty: Name
constructor(hello: string) {
this.hello = hello
}
getMsg() {
this.newProperty.consoleMsg()
}
}
let greeter = new Greeter('你好');
console.log(greeter)
console.log(greeter.name)
console.log(greeter.age)
greeter.getMsg()
运行结果:
如果Greeter类中没有属性name和age的话,类实例greeter需要设置为类型为any,否则无法使用greeter.name和greeter.age。因为name和age是是通过装饰器后期添加上去的!
如果想直接使用greeter.name和greeter.age,可以参考下面代码
function autoClassV2() {
// 泛型 T 继承了一个构造函数,则说明T是包含构造函数的一种类型
return function autoClass<T extends {
new(...args: any[]): any }>(constructor: T) {
return class extends constructor {
name = "new property";
age = "override";
}
}
}
class Test {
property = "property";
hello: string;
name: string
age: string
@auto(Name)
newProperty: Name
constructor(hello: string) {
this.hello = hello
}
getMsg() {
this.newProperty.consoleMsg()
}
}
// 将装饰后的类赋值给 Test1
const Test1 = autoClassV2()(Test)
let test1 = new Test1('你好');
console.log(test1)
console.log(test1.name)
console.log(test1.age)
test1.getMsg()
运行结果