The difficulty is that Array<T>.map
has a union type, that is:
function foo({ data }: Props) {
// x has the type:
// (<U>(callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[]) |
// (<U>(callbackfn: (value: string[], index: number, array: string[][]) => U, thisArg?: any) => U[])
let x = data.map;
}
This is a union of the functions, not a function with the parameters unioned.
If the definition was something like this:
function otherMap<U>(
data: string[] | string[][],
callbackfn:
(value: string | string[], index: number, array: string[] | string[][]) => U,
thisArg ?: any
): U[] {
// ...
}
You could use a type guard, or define a function that does exactly what you want instead of using Array.map
.
The type guard option is as follows:
function bar({ data }: Props) : string[] | string[][] {
if (isMultiDimArray(data)) {
return data.map(z => z);
}
return data.map(z => z);
}
function isMultiDimArray<T>(data: T[] | T[][]): data is T[][] {
if (data.length == 0) return false;
var firstItem = data[0];
return Array.isArray(firstItem);
}