Bashar Ali Labadi
Bashar Ali Labadi

Reputation: 1074

Functions Overloading in interface and classes - how to?

I have this interface :

interface IPoint {
    getDist(): string;
    getDist(x: number): any;
}

and I need a class to implement it but I can't get the right syntax to implement the getDist() method in the class..

class Point implements IPoint {
    // Constructor
    constructor (public x: number, public y: number) { }

    pointMethod() { }

    getDist() {
        Math.sqrt(this.x * this.x + this.y * this.y);
    }
    // Static member
    static origin = new Point(0, 0);
}

it says:

Class 'Point' declares interface 'IPoint' but does not implement it: Types of property 'getDist' of types 'Point' and 'IPoint' are incompatible:Call signatures of types '() => void' and '{ (): string; (x: number): any; }' are incompatible

What's the proper way to do this?

Thanks

Upvotes: 13

Views: 25016

Answers (4)

Pax Exterminatus
Pax Exterminatus

Reputation: 550

also you can use the default value

interface Foo{
    next()
    next(steps: number)
    prev()
    prev(steps: number)
}

next(steps: number = 1) {
    // ...
}

prev(steps: number = 1) {
    // ...
}

Upvotes: 3

Geraint
Geraint

Reputation: 1

The following is a variation on some of the above

class Position {
    x: number;
    y: number;

    constructor(x : number = 0, y : number = 0) {
        this.x = x;
        this.y = y;
    }    
}

class Pen {
    colour: string;

    constructor(colour: string) {
        this.colour = colour;
    }
}

class PlottingHead {
    isPenUp: boolean;
    pen: Pen;
    position: Position;

    constructor() {     
       this.penUp();
   }

   move(p: Position): void;
   move(x: number, y: number): void;
   move(x: number | Position, y?: number): void {
        if (typeof x === "number")
        {
            x = new Position(x, y);
        }
        this.penUp();
        this.position = x;
    }

    draw(x: number | Position, y?: number): void {
        if (typeof x === "number")
        {
            x = new Position(x, y);
        }
        this.penDown();
        this.position = x;
    }

    penDown(): void {
        this.isPenUp = false;
     }

    penUp(): void {
        this.isPenUp = true;
    }

    onChangePen(newPen: Pen) {
        this.penUp();
        this.pen = newPen;
    }    
}

The move function takes either a single position object or a pair of numeric values. This can obviously be extended as required.

Upvotes: 0

Fenton
Fenton

Reputation: 250902

When you declare the function in the class you need to decorate it with the overloads:

getDist(): string;
getDist(x: number): any;
getDist(x?: number): any {
    // your code
 }

Upvotes: 9

Matt Ball
Matt Ball

Reputation: 359786

This answer describes how to implement method overloading in TypeScript, and it's not pretty:

interface IPoint {
    getDist(): string;
    getDist(x: number): any;
}

class Point implements IPoint {
    // Constructor
    constructor (public x: number, public y: number) { }

    pointMethod() { }

    getDist(x?: number) {
         if (x && typeof x == "number") {
             return 'foo';
         } else {
             return 'bar';
         }
    }
}

N.B. with the particular combination of declared return types in the interface, you are limited to returning strings from getDist.

Upvotes: 5

Related Questions