In one of my projects, I have a function that executes an asynchronous operation over a collection. I want to add typings to this function for better IDE support - specifically, I want the IDE to infer that the first parameter in the callback function is of the same type as the elements in the array.
Here is the original function:
export async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}
I tried adding explicit typings like this, but encountered a problem:
export async function asyncForEach<T>(
items: T[],
callback: (item: T, idx: number, items: T[]) => Promise<any>
): Promise<void> {
for (let index = 0; index < items.length; index += 1)
await callback(items[index], index, items);
}
However, with this setup, I faced the following scenarios:
- When the first parameter was a typed array <T>[], the first callback parameter was correctly inferred as <T>
- When the first parameter was an untyped array [], the first callback parameter was correctly inferred as any
- PROBLEM: When the first parameter was an "any" typed variable, the first callback parameter was now inferred as "unknown" instead of "any". This change caused build issues with legacy code that relied on accessing properties of the "any" variable, which broke when the variable became "unknown".
I attempted to use a ternary operator in the callback parameter typing to address this issue, but it did not work successfully - the compiler failed to build and type inference stopped working.
export async function asyncForEach<T>(
items: T[],
callback: (item: T extends unknown ? any : T, idx: number, items: T[]) => Promise<any>
): Promise<void> {
for (let index = 0; index < items.length; index += 1)
await callback(items[index], index, items);
}
If anyone knows how to resolve the
(item: T extends unknown ? any: T,
part, I would greatly appreciate your help.
Thank you in advance for any assistance provided.