The challenge lies in the fact that the Array<T>.map
function has a union type, which means it can be:
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 union represents different functions, not a single function with unioned parameters.
If the definition were structured like this:
function otherMap<U>(
data: string[] | string[][],
callbackfn:
(value: string | string[], index: number, array: string[] | string[][]) => U,
thisArg ?: any
): U[] {
// ...
}
You could consider implementing a type guard or creating a custom function tailored to your specific needs, instead of relying on Array.map
.
One approach using a type guard is demonstrated below:
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);
}