#How to get the return type of a generic Higher Order Function?
17 messages · Page 1 of 1 (latest)
async function example<T extends ...>(action: () => ReturnType<typeof secureAction<T>>) {
// ...
}
The same constraint as secureAction so you can pass to it.
Why is execute using a new Promise?
That doesn't answer why you need a new Promise.
new Promise is only necessary if you want to turn callback style API into promise style, eg like what you did with setTimeout (because that's a callback style API)
But anyways that's irrelevant to your original question, you can fix execute by doing:
async function execute<T>(action: () => Promise<T | { reauthRequired: boolean }>) {
const response = await action()
if (response && typeof response === 'object' && 'reauthRequired' in response) {
// ...
return
}
return response
}
The guard clause gets a bit more complicated because you are not sure if action always returns an object, if you are fine with limiting that though, you can also do:
async function execute<T extends object>(action: () => Promise<T | { reauthRequired: boolean }>) {
const response = await action()
if ('reauthRequired' in response) {
// ...
return
}
return response
}
I mean, you are also hardcoding if ('reauthRequired' in response) { already.
Sure, change it to:
async function execute<T extends object>(action: ReturnType<typeof secureAction<() => T>>) {
It's still kind of fragile because it relies on secureAction returning certain shapes
If you want to improve it even more:
async function execute<T extends object>(
action: () => ReturnType<ReturnType<typeof secureAction<() => T>>>,
) {
// ...
}
Then just remove the generic constraint and add back in the null and object checks.
You can't resolve response as T inside the branch when the action failed and need reauth.
async function execute<T>(action: () => ReturnType<ReturnType<typeof secureAction<() => T>>>) {
return new Promise<T | undefined>(async (resolve) => {
const response = await action()
if (response && typeof response === 'object' && 'reauthRequired' in response) {
resolve(undefined)
} else {
resolve(response)
}
})
}