michael michael - 3 months ago 23
TypeScript Question

typescript: how do I overload a constructor?

I am trying to overload a class constructor, but I don't seem to get the concept. I keep getting

overload signature is not compatible with function implementation


This is what I'm looking at:

interface IGeoJson {
type: string,
coordinates: [number,number]
}

abstract class GeoJson implements IGeoJson {

constructor (public type: string, public coordinates: [number,number]) {}

toJson() : string {
return JSON.stringify(this);
}
}

class GeoJsonPoint extends GeoJson {

/**
* err: overload signature is not compatible with function implementation
*/
// constructor ( obj : IGeoJson);
constructor ( obj : [number, number]) {
let [longitude, latitude] = obj;
if (longitude && latitude) {
super("Point", [longitude, latitude]);
}
else {
let {type, coordinates} = obj;
if (type && coordinates) {
GeoJsonPoint.fromJson(obj);
}
}
}

static fromJson ( { type, coordinates } : IGeoJson) : GeoJsonPoint {
if (type != 'Point') throw new Error("Error, expecting type=Point");
let [longitude, latitude] = coordinates;
return new GeoJsonPoint([longitude, latitude]);
}
}





/**
* runtime
*/

let here = new GeoJsonPoint([10.123,20.456]);
let hereAsJson = here.toJson();
console.log('here:' + hereAsJson);


let obj :IGeoJson = JSON.parse(hereAsJson);
let hereFromJson = GeoJsonPoint.fromJson(obj);
console.log('here From JSON.parse():' + hereFromJson.toJson())


I am trying to overload the constructor so I can do the following:

let obj = JSON.parse(hereAsJson);
let hereFromOverloadedConstructor = new GeoJsonPoint(obj);
console.log('here From overloaded constructor:' + hereFromOverloadedConstructor.toJson())

Answer

It should be:

constructor (obj : IGeoJson);
constructor (obj : [number, number]);
constructor(obj: any) {
    let [longitude, latitude] = obj;
    if (longitude && latitude) {
        super("Point", [longitude, latitude]);
    } else {
        let {type, coordinates} = obj;
        if (type && coordinates) {
            GeoJsonPoint.fromJson(obj);
        }
    }
}

(code in playground)

But there's a problem with your code as you don't call super when you get a IGeoJson object.
Also, it can all be done like this:

constructor(obj: IGeoJson | [number, number]) {
    if (obj instanceof Array) {
        super("Point", obj);
    } else {
        super(obj.type, obj.coordinates);
    }
}

(code in playground)