由于奇怪的类型接口,无法解析的推送方法

Unresolved push method because of strange type interfacing

本文关键字:方法 于奇怪 类型 接口      更新时间:2023-09-26

我创建了一个这样的模块:

module GeoJSON {    
    export interface position {
        (): number[];
    }
    export interface coordinateArray {
        () : position[];
    }
    export interface polygonRings {
        (): position[][];
    }
    export class GeometryType {
        public static Point: string = "Point";
        public static LineString: string = "LineString";
        public static Polygon: string = "Polygon";
        public static MultiPoint: string = "MultiPoint";
        public static MultiLineString: string = "MultiLineString";
        public static MultiPolygon: string = "MultiPolygon";
        public static MultiGeometry: string = "MultiGeometry";
    }
    export interface Geometry {
        type?: string;
    }
    export interface Point extends Geometry {
        coordinates: position;
    }
    export interface LineString extends Geometry {
        coordinates: coordinateArray;
    }
    export interface Polygon extends Geometry {
        coordinates: polygonRings;
    }
    export interface MultiPolygon extends Geometry {
        coordinates: polygonRings[];
    }
    export interface MultiPoint extends Geometry {
        coordinates: coordinateArray;
    }
    export interface MultiLineString extends Geometry {
        coordinates: polygonRings;
    }
    export interface GeometryCollection extends Geometry {
        geometries: Geometry[];
    }
}

当我使用它,我得到一个愚蠢的错误。push是一个未解析的方法…

var lineString: GeoJSON.LineString = <GeoJSON.LineString> this._myGeometry;
lineString.coordinates.push(position);

我试图将坐标投射到GeoJSON.position[]上。代码编译,但JavaScript抛出一个错误:(

(<GeoJSON.position[]> lineString.coordinates).push(position);

如何使push在这里可见?我不能将coordinates的类型从coordinateArray更改为position[],因为稍后JSON.stringify将返回不同的JSON数据,服务器不会回答。

泛型对TypeScript来说仍然是一个开放的工作项。因此,虽然您可以让positioncoordinateArraypolygonRings扩展Array来知道push方法存在,但类型仍然无法匹配。lib.d.ts中的Array使用了一个hacky _element,在泛型实现之前由编译器专门处理。

您可以将Array的定义复制到position中,并将_element的所有实例替换为number,但这感觉真的很难看。我要么用数字[]替换position的所有实例,要么给出位置x和y(和z)成员。

你的运行时问题几乎肯定是你从来没有正确构造LineString,所以lineString.coordinates是未定义的。不要强制转换为LineString,让接口成为一个类,并在构造函数中设置所有成员。即:

export interface position {
    x: number;
    y: number;
}
export class LineString implements Geometry {
    coordinates: position[];
    constructor() {
        this.coordinates = [];
    }
}
var lineString: GeoJSON.LineString = new GeoJSON.LineString();
lineString.coordinates.push({ x: 0, y: 0 });

要清楚,当你写这个:

export interface coordinateArray {
    () : position[];
}

您所描述的是具有呼叫签名的类型。()的意思是"你可以用零参数调用我",而不是"这就是我"。编译器期望您像这样使用coordinateArray:

var x: coordinateArray = /* something */;
var y = x(); // y: position[]