Q:

In NestJs, how to inject a service based on its interface?

I have the next module: payment.module.ts
@Module({
  controllers: [PaymentController],
})
export class PaymentModule {}

And in the next service I want to have access to a service based on an interface
payment.service.ts
export class PaymentService {
   constructor(private readonly notificationService: NotificationInterface,
}

notification.interface.ts
export interface NotificationInterface {
  // some method definitions
}

notification.service.ts
@Injectable()
export class NotificationService implements NotificationInterface {
  // some implemented methods
}

The question is how do I inject NotificationService based on NotificationInterface?

A:

This is the solution I found... 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:
payment.module.ts
@Module({
  providers: [
    {
      provide: 'NotificationInterface',
      useClass: NotificationService
    }
  ]
})
export class PaymentModule {}

payment.service.ts
export class PaymentService {
   constructor(@Inject('NotificationInterface') private readonly notificationService: NotificationInterface,
}

