Creating a Javascript Function with Dual Meanings for the First Argument

Ole Ersoy
2 min readJun 15, 2024

--

Photo by Jesper Aggergaard on Unsplash

Scenario

We want to create a range function that accepts multiple arguments with this type of interface.

export function range(
start: number,
end: number,
step?: number,
): Iterable<number>;

When the function is called with more than one parameter ( range(10,20,2) ), the above interface is used.

However if we called the function with only one argument ( range(10) ), then we want start to default to 0 and step to default to 1 .

Approach

We will use the range function from Lit Element to illustrate this.

This is how it is implemented.


/**
* Returns an iterable of integers from `start` to `end` (exclusive)
* incrementing by `step`.
*
* If `start` is omitted, the range starts at `0`. `step` defaults to `1`.
*
* @example
*
* ```ts
* render() {
* return html`
* ${map(range(8), () => html`<div class="cell"></div>`)}
* `;
* }
* ```
*/
export function range(end: number): Iterable<number>;
export function range(
start: number,
end: number,
step?: number,
): Iterable<number>;
export function* range(startOrEnd: number, end?: number, step = 1) {
const start = end === undefined ? 0 : startOrEnd;
end ??= startOrEnd;
for (let i = start; step > 0 ? i < end : end < i; i += step) {
yield i;
}
}

When end is undefined start becomes zero. The step parameter is initialized to 1 in the function parameter declaration.

--

--