Home > Back-end >  Can I define a type that is extended by generics?
Can I define a type that is extended by generics?

Time:10-14

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;
  }
}

TS Playground

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
  • Related