Nest: Typescript - Interface injecting

Created on 8 May 2017  路  6Comments  路  Source: nestjs/nest

Hi,

is it possible to inject a component based on its interface?

Let's assume the following component:

class UserRepository implements IUserRepository

This component is injected into the controller by interface from which is implemented:

export class UserController {
    constructor(private userService: IUserRepository) {}

It would be great to be able to set dependencies as follows:

@Module({
    controllers: [ UsersController ],
    components: [
        { provide: IUserRepository, useClass: UserRepository }
    ],
})

Thanks

Most helpful comment

Using Interfaces as value types is not possible as they only exist during development. After transpiling interfaces no longer exist resulting in empty object values. There is a solution for your problem though using string keys as provide values and the inject decorator:

@Module({
    controllers: [ UsersController ],
    components: [
        { provide: 'IUserRepository', useClass: UserRepository }
    ],
})
export class UserController {
    constructor(@Inject('IUserRepository') private userService: IUserRepository) {}

Also see here

All 6 comments

I've been wondered the same thing - would definitely be a useful feature.

So far I've been injecting the concrete classes and just storing them in an instance var typed as the interface to at least keep things decoupled as much as possible.

Using Interfaces as value types is not possible as they only exist during development. After transpiling interfaces no longer exist resulting in empty object values. There is a solution for your problem though using string keys as provide values and the inject decorator:

@Module({
    controllers: [ UsersController ],
    components: [
        { provide: 'IUserRepository', useClass: UserRepository }
    ],
})
export class UserController {
    constructor(@Inject('IUserRepository') private userService: IUserRepository) {}

Also see here

Hi @jezikk
As @JulianBiermann said - it is not possible. TypeScript types disappear after compilation. They are not a part of the language.

How would one export a string keyed component?

I tried this:

const usersServiceProvider = { provide: 'IUsersService', useClass: UsersService };

@Module({
    components: [usersServiceProvider],
    controllers: [UsersController],
    modules: [DatabaseModule, CryptoModule],
    exports: [usersServiceProvider]
})

but that results in the following error:

[Nest] 18   - 5/9/2017, 11:08:36 PM   [ExceptionHandler] You are trying to export unkown component (undefined). Remember - your component should be listed both in exports and components arrays!

Hi @zachgrayio,

It was an issue of the previous version. The bug is already resolved, just update package (1.0.6)

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

menme95 picture menme95  路  3Comments

2233322 picture 2233322  路  3Comments

cojack picture cojack  路  3Comments

thohoh picture thohoh  路  3Comments

yanshuf0 picture yanshuf0  路  3Comments