0

I have seen TypeScript libraries that by just add an annotation on the class, it is capable of injecting this class into the constructor of other class by just declaring the argument type.

It goes something like this:

@someAnnotation()
class Foo {
}

@someAnnotation()
class Bar {
}

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

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

Then magically, the libary can somehow get these

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

How is this possible ? What is the code behind the annotation

An example of this library is typedi

2
  • So the code for typedi is openly available... Why not take a peek? github.com/typestack/typedi/tree/develop/src/decorators Commented Sep 8, 2020 at 21:06
  • Those are called decorators not annotations. Annotations were a feature proposed and subsequently scrapped from ECMAScript. Commented Sep 8, 2020 at 23:48

1 Answer 1

1

By looking at the code of typedi, I found that they use a library called reflect-metadata

And the job is done like this

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

To be more specific, import 'reflect-metadata' must be called before anything else.

Also, the decorator is required. But any would work, even an empty function decorator

function Service(target: any) {

}

Used like this

@Service
class A {
    id = 'A'

    constructor(foo: Foo, bar: Bar) {
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.