So at work we use these the types which create the base of of our Geometries:
export type GeoJSON = Geometry | Feature;
export type GeoJsonTypes = GeoJSON['type'];
export interface GeoJsonObject { type: GeoJsonTypes; }
export interface Point extends GeoJsonObject {
type: 'Point';
coordinates: number[];
}
export interface MultiPoint extends GeoJsonObject {
type: "MultiPoint",
coordinates: number[][];
}
export type Geometry =
| Point
| MultiPoint
export interface Feature<G extends Geometry = Geometry>
extends GeoJsonObject {
type: 'Feature';
geometry: G;
}
The issue is that we end up having to create separate typeguard for each Geometry:
export const isPointGeometry = (g: Geometry): g is Point => {
return (g as Point).type === 'Point';
};
I tried to create a generic typeguard by writing:
export function isGeometry<T extends Geometry, G extends GeoJsonObject['type']>(feature: T, geometry: G): feature is T {
return feature && feature && feature.type === geometry;
}
But to no avail. as i still get an issue with? Anyone got an idea?
export function coordinatesFor(f: Feature<Point | MultiPoint>) {
if (isGeometry(f.geometry, 'Point')) {
return f.geometry.coordinates ?? []; // Expected Feature<Point> but got Feature<Point | MultiPoint>
}
return [];
}
Try this way:
Here we do two things:
We infer type
Gbased onTargument in order to make sure, thatGis always compatible with givenTand make it impossible to call the function with wrong combination of arguments, such as:isGeometry(somePoint, 'Polygon').With
Extract<T, { type: G }>in return type we pick thoseGeometryunion members, that are compatible to (the geometry we are looking for){ type: G }.