How do you create a union type for a component's services?

141 views Asked by At

I have a component that makes a call to a service method. This component is a base component so child components are providing the service using super() as shown below:

export class ParentComponent {
  constructor(protected myService: ServiceOne | ServiceTwo | ServiceThree | any) {

  }

  register(formData) {
    let response = await this.myService.register(formData);
  }
}

export class ChildComponent extends ParentComponent {
  constructor(protected serviceOne: ServiceOne) {
    super(serviceOne);
  }
}

Each service (ServiceOne, ServiceTwo, and ServiceThree) all extend from the same base service with a shared register() method.

@Injectable()
export class ServiceOne extends BaseService {
  register(user) {
    return this.post('url', user);
  }
}

export class BaseService {
  protected post(url, data) {
    return this.http.post(url, data);
  }
}

All of this works just fine as long as I include any in ParentComponent. But when I remove any from the union type, I get:

Cannot invoke an expression whose type lacks a call signature. Type ‘(user => Promise<any>) | (user => Promise<any>) | (user => Promise<any>)’ has no compatible call signature.

Is there a clean way to do this without having to resort to any?

1

There are 1 answers

0
clo5ure On BEST ANSWER

So as @DeborahK suggested, an interface was the way to go.

Here's the interface and updated constructor. (Update Promise<> wrapper as needed).

interface DynamicService {
  register: (service) => (Promise<ServiceOne | ServiceTwo | ServiceThree>);
}

export class ParentComponent {
  constructor(protected myService: DynamicService) {

  }

  register(formData) {
    let response = await this.myService.register(formData);
  }
}

export class ChildComponent extends ParentComponent {
  constructor(protected serviceOne: ServiceOne) {
    super(serviceOne);
  }
}