0

I have an interface:

export interface EditAction {
    action: (p?: Point) => any;
    undo(): void;
    redo(): void;
    complete: () => any;
    dispose: () => void;
}

Then there is a concrete class that implements this interface:

export class LineAction implements EditAction {
      action(x: number, y: number) {
        alert('ok');
    }
}

export class PointAction implements EditAction {
  action(p: Point) {
    alert('ok');
}

}

The method action() in all implementations has different number of parameters.

How to overload it?

action: (p?: Point) => any;
action: (x:number, y: number) => any;
5
  • 2
    So how would the consumer of the interface know what arguments to pass? If they use the implementation then adding the action in the interface would have no added benefit? Commented Apr 30, 2021 at 18:11
  • Are you saying that each implementation has the same overloads, or each implementation has a different set of overloads? Commented Apr 30, 2021 at 18:18
  • I just want to say tht there is a entry point in class that consumer should call at first Commented Apr 30, 2021 at 18:19
  • It seems to me that you are applying the wrong tool to the problem (frozen fish to hammer a nail as it may look like and act like a hammer). If each implementation is supposed to have different set of parameters, you cannot enforce an interface for the action. You could however apply different solutions (factory pattern, builder pattern) though that requires more insight what your actions are supposed to do. Commented Apr 30, 2021 at 18:35
  • 1
    You may want to go in the direction of using a generics for your action method. action: (input: T) => R. Commented Apr 30, 2021 at 18:38

2 Answers 2

1

Your interface definition isn't quite right, once you fix the issues, you cou easily define overrides:

export interface EditAction {
    action(p?: Point): any;
    action(x: number, y: number): any;
    /* ... */
}

In your class you can implement the overrides by creating signature that match the interface and an underlying method that can handle all possible parameters:

export class PointAction implements EditAction {
    action(p?: Point): any;
    action(x: number, y: number): any;
    action(xOrP: Point | number, y?: number) {
      const p = (typeof xOrP === 'number') ? { x: xOrP, y } : xOrP;
      // do stuff...
    }
    /* ... */
}

If your implementing an interface you have to handle all possible parameters. You might be better off creating a generic interface:

export interface EditAction<T> {
    action: (t?: T) => any;
    undo(): void;
    redo(): void;
    complete: () => any;
    dispose: () => void;
}
export class LineAction implements EditAction<Line> {
  action(line: Line) {
     alert('ok');
  }
}
export class PointAction implements EditAction<Point> {
  action(p: Point) {
    alert('ok');
  }
}
Sign up to request clarification or add additional context in comments.

Comments

1

If I understand your issue correctly, I think you might want to leverage generics and the Parameters utility type rather than overloads. For example:

export interface EditAction<T extends ((...args: any) => R) = ((...args: any) => any), R = any> {
  action(...params: Parameters<T>): R
  // ....
}

// Implementation:
export class LineAction implements EditAction {
  action(x: number, y: number) {
    alert('ok');
  }
}

// Optionally, be explicit
export class PointAction implements EditAction<(p: Point) => any, Point> {
  action(p: Point) {
    alert('ok');
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.