Reputation: 2585
I have a function that is defined as so:
function getRangeBounds(start: number, stop?: number, step?: number) {
if (step === undefined) step = 1;
const actualStart = start !== undefined && stop !== undefined ? start : 0;
const actualStop = stop === undefined ? start : stop;
return [actualStart, actualStop, step];
}
I want this function's arguments to be typed and be reusable. So I did:
type Range = Parameters<typeof getRangeBounds>;
I want the type Range
to be reusable across a couple more functions, namely range
and mapRange
that will have the following signatures respectively:
export function range(...args: Range): ReadonlyArray<number> {
/* this will call getRangeBounds at some point */
}
export function mapRange(...rangeArgs: Range, mapper: MapFunc<number> = IdentityMapper) {
return range(rangeArgs).map(mapper); /* code does not compile */
}
How can I make these functions behave in a way the contract Range
is honored by them all and also be possible to use extra args in some functions like the mapRange
above?
Edit: I fixed the compilation error above, so mapRange
looks like this now:
export function mapRange(rangeArgs: Range, mapper: MapFunc<number>) {
return range(...rangeArgs).map(mapper);
}
But I now need to call the function like this:
mapRange([start, stop, step])
Upvotes: 3
Views: 1605
Reputation: 74500
Some options to add extra parameters to Range
for other functions:
function mapRangeRest(mapper: MapFunc<number>, ...rangeArgs: Range) { ... }
mapRangeRest(mapFunc, 1)
mapRangeRest(mapFunc, 1, 2)
Option 2: Currying
function mapRangeCurry(...rangeArgs: Range_): (mapper: MapFunc<number>) { ... }
mapRangeCurry(1)(mapFunc)
mapRangeCurry(1, 2)(mapFunc)
Option 3 (TS 4.0): Variadic tuples
function mapRangeVT<T extends Range_>(...rangeArgs: [...T, MapFunc<number>]) {...}
mapRangeVT(1, mapFunc)
mapRangeVT(1, 2, mapFunc)
If you can update to the latest TS version, option 3 probably fits best, as function shape is not changed.
Upvotes: 2