- Notifications
You must be signed in to change notification settings - Fork 13.2k
Description
I'm trying to write a function which transforms the coordinates of any type of GeoJSON geometry. The coordinates of a Geometry can be either number[] (a Point), number[][] (a LineString), number[][][] (a Polygon) or number[][][][] (a MultiPolygon). I have a recursive implementation which works but does not type check.
TypeScript Version: 3.7.2
Search Terms:
- 2349
Code
type Position = number[]; function isNestedArray<T extends any[]>(x: T | T[]): x is T[] { return Array.isArray(x[0]); } export function transformCoordArray( coords: Position | Position[] | Position[][], fn: (pt: Position) => Position ): any[] { if (isNestedArray(coords)) { coords; // type is Position[] | Position[][] return coords.map(c => transformCoordArray(c, fn)); // ~~~ This expression is not callable. } else { coords; // type is Position return fn(coords); } }The full error message is:
This expression is not callable. Each member of the union type ' (<U>(callbackfn: (value: Position, index: number, array: Position[]) => U, thisArg?: any) => U[]) | (<U>(callbackfn: (value: Position[], index: number, array: Position[][]) => U, thisArg?: any) => U[]) ' has signatures, but none of those signatures are compatible with each other.(2349) The call is valid because c's type should be Position | Position[], which is assignable to Position | Position[] | Position[][].
Interestingly, I can make the error go away by assigning to a new variable which has a broader type ((Position | Position[])[]):
(playground)
export function transformCoordArray( coords: Position | Position[] | Position[][], fn: (pt: Position) => Position ): any[] { if (isNestedArray(coords)) { coords; // type is Position[] | Position[][] const c2: (Position | Position[])[] = coords; return c2.map(c => transformCoordArray(c, fn)); // ok } else { coords; // type is Position return fn(coords); } }Expected behavior:
No error.
Actual behavior:
The given error.
Playground Link: playground
Related Issues: