13

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

4 Answers 4

9

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
 }
Sign up to request clarification or add additional context in comments.

5 Comments

You need not write the second declaration. It works even without that
@S.RaviKiran you need both overload declarations as you can't call the implementation on overloaded functions. You can try this out in the TypeScript Playground. typescriptlang.org/Playground
@S.RaviKiran Post your example.
it works without adding the declarations but to get overloading in Visual studio auto complete you need to add overloading decelerations.
And static typing for the return values, which are different.
5

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.

Comments

3

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) {
    // ...
}

Comments

0

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.

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.