import { Injectable, Optional } from '@nestjs/common'; @Injectable() export class ConsumerService { constructor(@Optional() private readonly optionalService?: OptionalService) {} getStatus() { return this.optionalService ? 'Service available' : 'Service missing'; } } // Assume OptionalService is NOT provided in any module
The @Optional() decorator tells NestJS that the provider might not be registered. If it is missing, NestJS injects undefined instead of throwing an error. So the injected dependency will be undefined, making the condition false and returning 'Service missing'.
import { Injectable, Optional } from '@nestjs/common'; @Injectable() export class ExampleService { constructor( /* ??? */ ) {} }
The @Optional() decorator must be placed immediately before the parameter it decorates. Option A correctly places it before the parameter declaration. Options A and C have invalid syntax. Option A uses TypeScript optional parameter syntax but does not mark the provider as optional for NestJS.
consumer.getMessage()?import { Injectable, Optional } from '@nestjs/common'; @Injectable() export class OptionalService { getMessage() { return 'Hello from OptionalService'; } } @Injectable() export class ConsumerService { constructor(@Optional() private readonly optionalService?: OptionalService) {} getMessage() { return this.optionalService?.getMessage() ?? 'No service available'; } } // Module setup: // @Module({ // providers: [ConsumerService] // OptionalService is NOT provided // })
The optionalService is not provided, so it is undefined. The method uses optional chaining ?. to safely call getMessage() only if the service exists. Since it doesn't, the fallback string 'No service available' is returned.
constructor(@Optional() private readonly service: SomeService) {}
If SomeService is not provided in any module, why might this code still cause a runtime error?import { Injectable, Optional } from '@nestjs/common'; @Injectable() export class ConsumerService { constructor(@Optional() private readonly service: SomeService) { console.log(this.service.getName()); } }
The @Optional() decorator makes NestJS inject undefined if the provider is missing. The constructor then tries to call getName() on undefined, which causes a runtime error: TypeError: Cannot read property 'getName' of undefined.
When a provider is marked with @Optional() and is not registered, NestJS injects undefined instead of throwing an error. This allows the consuming class to check for the provider's presence and handle its absence gracefully.