Typescript получает конструктор типов для каждого аргумента конструктора

#javascript #typescript #dependency-injection #annotations #static-typing

#javascript #typescript #внедрение зависимостей #аннотации #статическая типизация

Вопрос:

Я видел библиотеки TypeScript, которые, просто добавив аннотацию к классу, способны вводить этот класс в конструктор другого класса, просто объявляя тип аргумента.

Это выглядит примерно так:

 @someAnnotation()
class Foo {
}

@someAnnotation()
class Bar {
}

@someAnnotation()
class A {
    constructor(foo: Foo, bar: Bar) {
    }
}

@someAnnotation()
class B {
    constructor(a: A) {
    }
}
  

Затем, волшебным образом, библиотека может каким-то образом получить эти

 /// how do they get these? 
const constructorArgumentsTypesOfA = [Foo, Bar]
const constructorArgumentsTypesOfB = [A]
  

Как это возможно? Какой код стоит за аннотацией

Примером этой библиотеки является typedi

Комментарии:

1. Таким образом, код для typedi находится в открытом доступе… Почему бы не взглянуть? github.com/typestack/typedi/tree/develop/src/decorators

2. Они называются декораторами, а не аннотациями. Аннотации были функцией, предложенной и впоследствии удаленной из ECMAScript.

Ответ №1:

Просмотрев код typedi, я обнаружил, что они используют библиотеку под названием reflect-metadata

И работа выполняется следующим образом

 const paramTypes = Reflect.getMetadata('design:paramtypes', A);
console.log(paramTypes)
  

Чтобы быть более конкретным, import 'reflect-metadata' должен вызываться перед чем-либо еще.

Кроме того, требуется декоратор. Но любой будет работать, даже декоратор пустой функции

 function Service(target: any) {

}
  

Используется следующим образом

 @Service
class A {
    id = 'A'

    constructor(foo: Foo, bar: Bar) {
    }
}