【问题标题】:TypeScript decorators, getting constructor argument types and injectionTypeScript 装饰器,获取构造函数参数类型和注入
【发布时间】:2017-09-14 06:12:07
【问题描述】:

假设您有一个像这样的类,并附加了 Router 装饰器。

@Router
class AuthRouter {

    constructor(private cacheService: CacheService) {}
}

如何从Router 装饰器中获取构造函数参数类型?假设我们存储了一个 CacheService 的单例,如果我们知道类名“CacheService”,我们就可以访问它。

function Router(target) {

    // somehow get the constructor class name
    const dependencyNames = 'CacheService' // an array if multiple args in constructor

    // getSingleton is a function that will retrieve
    // a singleton of the requested class / object
    return new target(getSingleton(dependencyNames))
}

因此,每当我们使用AuthRouter 时,都会将CacheService 注入其中。

【问题讨论】:

  • 这适用于其他语言,如使用反射的 C#,它允许在运行时访问所有类型。但 TypeScript 不同。它不将类型信息包含在运行时中,因此在此期间不能使用类型。您可以尝试的解决方案是 RegExping target.toString() 用于 args names,然后进行单例注入
  • 看看parameter decorator example,他们做了类似的事情,但我不确定这是否适用于构造函数。但似乎你错过了类装饰器的意义。它不应该返回类的实例,如果返回,那么它必须是构造函数。
  • @NitzanTomer 我明白,我只是在摆弄装饰器以了解它们是如何工作的。我想知道Angular 如何在内部做到这一点。返回一个新的构造函数仅仅是Decorators的设计原则还是会产生“负面”副作用?
  • @jevgenig 我希望这可以通过使用reflect-metadata 库来实现。
  • 我不确定我是否明白你在问什么。你可以选择不从装饰器函数返回任何东西,但如果你这样做,它需要是一个构造函数。有什么负面影响?

标签: typescript decorator ecmascript-2016


【解决方案1】:
import 'reflect-metadata'

function Router(target) {
    const types = Reflect.getMetadata('design:paramtypes', target);
    // return a modified constructor
}

请注意,您调用的 getMetadata 没有第三个参数。 types 将是构造函数参数的数组。 types[0].name === 'CacheService' 在你的情况下。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-21
    • 1970-01-01
    • 2021-02-07
    • 2017-09-14
    • 2018-05-08
    • 2019-07-23
    • 2017-04-09
    • 2017-05-04
    相关资源
    最近更新 更多