Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 28 additions & 14 deletions packages/turf-helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,30 +207,39 @@ export function feature<
* var geometry = turf.geometry(type, coordinates);
* // => geometry
*/
export function geometry(
type:
export function geometry<
T extends
| "Point"
| "LineString"
| "Polygon"
| "MultiPoint"
| "MultiLineString"
| "MultiPolygon",
>(
type: T,
coordinates: any[],
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a simliar fashion, we could narrow this any[] based on T, but that would be a breaking change, we can file it against the 8.0 milestone. I suppose you could also just make the case that we should do this in 7.x, because it is explicitly a bug in the caller if they aren't passing in the correctly shaped coordinates. My only concern with that is some amount of weirdness with number[] vs [number, number] issues, which might crop up depending on how consumers wrote their own types.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The [number, number] thing is going to haunt us forever 😅

_options: Record<string, never> = {}
) {
): {
Point: Point;
LineString: LineString;
Polygon: Polygon;
MultiPoint: MultiPoint;
MultiLineString: MultiLineString;
MultiPolygon: MultiPolygon;
}[T] {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had considered making this a named interface and mapping against that instead (GeometryTypeNameToType), and referencing that instead of as any below, but I opted to not increase the public API for a mapping we only used in a single place.

switch (type) {
case "Point":
return point(coordinates).geometry;
return point(coordinates).geometry as any;
case "LineString":
return lineString(coordinates).geometry;
return lineString(coordinates).geometry as any;
case "Polygon":
return polygon(coordinates).geometry;
return polygon(coordinates).geometry as any;
case "MultiPoint":
return multiPoint(coordinates).geometry;
return multiPoint(coordinates).geometry as any;
case "MultiLineString":
return multiLineString(coordinates).geometry;
return multiLineString(coordinates).geometry as any;
case "MultiPolygon":
return multiPolygon(coordinates).geometry;
return multiPolygon(coordinates).geometry as any;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This as any casts are a little unfortunate. The case statements don't actually narrow our understanding of T, and so we need to reaffirm that we know what we're doing here.

microsoft/TypeScript#33014

default:
throw new Error(type + " is invalid");
}
Expand Down Expand Up @@ -598,15 +607,20 @@ export function multiPolygon<P extends GeoJsonProperties = GeoJsonProperties>(
* // => collection
*/
export function geometryCollection<
G extends
| Point
| LineString
| Polygon
| MultiPoint
| MultiLineString
| MultiPolygon,
P extends GeoJsonProperties = GeoJsonProperties,
>(
geometries: Array<
Point | LineString | Polygon | MultiPoint | MultiLineString | MultiPolygon
>,
geometries: Array<G>,
properties?: P,
options: { bbox?: BBox; id?: Id } = {}
): Feature<GeometryCollection, P> {
const geom: GeometryCollection = {
): Feature<GeometryCollection<G>, P> {
const geom: GeometryCollection<G> = {
type: "GeometryCollection",
geometries,
};
Expand Down