Unable to automatically determine the template parameters from the handler's return type, still seeking a solution.
If you're willing to provide the template parameters manually, there is a workaround:
let i = 0;
async function someExternalThing() {
i += 1;
return i > 3;
}
async function chain<VAL, RET>(
input: VAL,
handler: (input: VAL, loop: (input: VAL) => Promise<RET>) => Promise<RET>
): Promise<RET> {
const loop = (input: VAL): Promise<RET> => handler(input, loop);
return loop(input);
}
const result = chain<string, string>('test', async (value, loop) => {
const ready = await someExternalThing();
if (ready) {
return value;
} else {
return await loop(value + '!');
}
});
result.then((value) => {
console.log(`Result: ${value}`)
})
Result: test!!!
Every type in the script is explicitly defined, no any
or unknown
.
Further exploration
This seems to be working:
async function chain<VAL, RET>(
input: VAL,
handler: (input: VAL, loop: (input: VAL) => Promise<RET>) => Promise<RET>
): Promise<RET> {
const loop = (input: VAL): Promise<RET> => handler(input, loop);
return loop(input);
}
const result = chain('test', async (value): Promise<string> => {
return value;
});
However, when introducing the loop
parameter, RET
reverts to unknown
. Appears to be a limitation of TypeScript's type inference mechanism at present. Potential for improvement in future iterations.
async function chain<VAL, RET>(
input: VAL,
handler: (input: VAL, loop: (input: VAL) => Promise<RET>) => Promise<RET>
): Promise<RET> {
const loop = (input: VAL): Promise<RET> => handler(input, loop);
return loop(input);
}
const result = chain('test', async (value, loop): Promise<string> => {
return value;
});