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: