I have a class that represents a configurable object, e.g.
class Device {
// ... code that manipulates the device
}
This device in turn can have services. Services are preferably known in compile type, but they have to be determined in initialisation of Device
. I want to be able to access a service if it is available, for example:
const device = new Device(new ControlService())
typeof device.control // = ControlService
//But
const device2 = new Device()
device.control // Compilation error because this device doesn't have the service.
Is there a way to achieve this with generics in TypeScript 4.0 and above?
CodePudding user response:
Basically what you want to achieve is doable with a simple interface. The Service interface will define the public methods and fields for a service, which you can use inside the device class. Then you can add any class instace to the device which implements this interface. Of course if this service or control is optional, you have to check if it exists before calling any methods on it.
interface Service { }
class Device {
service?: Service;
constructor(service?: Service) {
this.service = service;
}
}
class ControlService implements Service { }
const device1 = new Device(new ControlService());
console.log(device1.service); // ControlService
const device2 = new Device();
console.log(device2.service); // undefined
The device class can be extended to be generic of course:
class Device<S extends Service> {
service?: S;
constructor(service?: S) {
this.service = service;
}
}
CodePudding user response:
If I understand you correctly, you are looking for something like this:
class Device<T> {
constructor(
private control?: T
){}
public hasControlService = () => this.control
}
class ControlService {}
let device = new Device(new ControlService())
device.hasControlService() && console.log(typeof device.hasControlService()) // will print type
let device2 = new Device()
device2.hasControlService() && console.log(typeof device2.hasControlService()) // wont print anything