通过TypeScript中的装饰器向类添加属性 [英] Adding properties to a class via decorators in TypeScript

查看:1264
本文介绍了通过TypeScript中的装饰器向类添加属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在TypeScript的Decorator参考页面上,有一段代码被截断,该代码说明了如何使用类decorator覆盖构造函数:

On the TypeScript's Decorator reference page there is a code snipped that illustrates how to override the constructor with class decorator:

function classDecorator<T extends {new(...args:any[]):{}}>(constructor:T) {
    return class extends constructor {
        newProperty = "new property";
        hello = "override";
    }
}

@classDecorator
class Greeter {
    property = "property";
    hello: string;
    constructor(m: string) {
        this.hello = m;
    }
}

console.log(new Greeter("world"));

和日志中:

class_1 {
  property: 'property',
  hello: 'override',
  newProperty: 'new property' }

到目前为止,一切都很好.但是尝试通过点符号访问newProperty失败,并显示以下信息:

So far so good. BUT trying to access newProperty by dot notation fails with:

类型'Greeter'.ts(2339)上不存在属性'newProperty'

Property 'newProperty' does not exist on type 'Greeter'.ts(2339)

错误,并且未在VS Code的提示中列出.可以使用方括号表示法访问它,但TS警告

error and it's not listed in hints in VS Code. One can access it by bracket notation but TS warns that

元素隐式地具有"any"类型,因为类型"Greeter"没有索引签名.ts(7017)

Element implicitly has an 'any' type because type 'Greeter' has no index signature.ts(7017)

我错过了什么吗?如何通过Decorators以类型安全的方式实现添加新属性?我希望像普通的类成员一样具有正常的编译器支持.

Am I missing something? How to implement adding new properties via Decorators in type-safe way? I'd like to have normal compiler support just like with regular class members.

推荐答案

装饰器在设计上不能更改类的类型.这在讨论中还很久,直到装饰器提案完成后,团队不会改变行为.您可以将mixins用于此任务(有关ts中的 mixins )

Decorators by design can't change the type of a class. This is stil in discussion and it appears until the decorator proposal is finalized the team will not change the behavior. You can use mixins for this task (read about mixins in ts)

使用mixins的代码如下所示:

Using mixins the code would look something like:

function classDecorator<T extends { new(...args: any[]): {} }>(constructor: T) {
    return class extends constructor {
        newProperty = "new property";
        hello = "override";
    }
}

const Greeter = classDecorator(class {
    property = "property";
    hello: string;
    constructor(m: string) {
        this.hello = m;
    }
});
type Greeter = InstanceType<typeof Greeter> // have the instance type just as if we were to declare a class

console.log(new Greeter("world").newProperty);

这篇关于通过TypeScript中的装饰器向类添加属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆