In exercise #14 of typescript-exercises you get to annotate the following function:
export function map(mapper, input) {
if (arguments.length === 0) {
return map;
}
if (arguments.length === 1) {
return function subFunction(subInput) {
if (arguments.length === 0) {
return subFunction;
}
return subInput.map(mapper);
};
}
return input.map(mapper);
}
I've tried to tightly type it using generics but failed:
type Apply<In, Out> = (element: In) => Out;
declare function subFunction<In2, Out2>(subInput: In2[]): Out2[];
declare function subFunction(): typeof subFunction;
export function map<In, Out>(): typeof map;
export function map<In, Out>(mapper: Apply<In, Out>): typeof subFunction;
export function map<In, Out>(mapper: Apply<In, Out>, input: In[]): Out[];
export function map<In, Out>(mapper?: Apply<In, Out>, input?: In[]): ((typeof map) | (typeof subFunction) | Out[]) {
if (mapper === undefined) {
return map;
}
if (input === undefined) {
// Line 61 (the error) ahead
return function subFunction(subInput?: In[]): ((typeof subFunction) | Out[]) {
if (subInput === undefined) {
return subFunction;
}
return subInput.map(mapper);
};
}
return input.map(mapper);
}
The error is:
index.ts(61,9): error TS2322: Type '(subInput?: In[] | undefined) => Out[] | ...' is not assignable to type '{ <In2, Out2>(subInput: In2[]): Out2[]; (): typeof subFunction; } | { <In, Out>(): typeof map; <In, Out>(mapper: Apply<In, Out>): { <In2, Out2>(subInput: In2[]): Out2[]; (): typeof subFunction; }; <In, Out>(mapper: Apply<...>, input: In[]): Out[]; } | Out[]'.
Type '(subInput?: In[] | undefined) => Out[] | ...' is not assignable to type '{ <In2, Out2>(subInput: In2[]): Out2[]; (): typeof subFunction; }'.
Type 'Out[] | ((subInput?: In[] | undefined) => Out[] | ...)' is not assignable to type 'any[]'.
Type '(subInput?: In[] | undefined) => Out[] | ...' is missing the following properties from type 'any[]': pop, push, concat, join, and 25 more.
When I change the return type of subFunction
@ line 61 to any
, the error disappears.
What am I doing wrong?