Reputation: 482
How can I force environment.service to only accept values which implement ServiceInterface?
interface ServiceInterface {
id: string
}
class ServiceA implements ServiceInterface {
id = 'a'
}
class ServiceB implements ServiceInterface {
id = 'b'
}
interface Environment {
service: ServiceInterface
}
const environment: Environment = {
service: ServiceA // TS2741: Property 'id' is missing in type 'typeof ServiceA'...
}
I want people to be able to switch out the service in the environment for their own implementation of the service, but only as long as their new implementation adheres to ServiceInterface.
The reason I cannot use an instance service: new ServiceA()
is because I am using Angular, where the dependency injection takes care of instantiating the class. I have to supply the class to the dependency injection system. To do that I import my environment file, where I need to make sure that the class added there implements the interface.
Upvotes: 0
Views: 331
Reputation: 482
Found the solutions thanks to this
interface ServiceInterface {
id: string
}
type Implements<T> = new (...args: any[]) => T;
class ServiceA implements ServiceInterface {
id = 'a'
}
class ServiceB implements ServiceInterface {
id = 'b'
}
interface Environment {
service: Implements<ServiceInterface>
}
const environment: Environment = {
service: ServiceB
}
Upvotes: 1
Reputation: 15323
When you write
const environment: Environment = {
service: ServiceA
}
the value of the service
key is not an instance of the ServiceA
class, but the class itself.
You need to pass an actual instance of the class to satisfy the constraint:
const environment: Environment = {
service: new ServiceA()
}
Upvotes: 2