-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Handle union type of void and Promise<void> in return types #43921
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Related: #42709 |
Any updates on this? |
SonarLint rule |
I don't think function mySecondOrderFn<T>(firstOrderFn: () => T | Promise<T>) {
return async () => {
console.log("Calling firstOrderFn()")
const output = await firstOrderFn()
console.log("Finished calling firstOrderFn()")
}
} As for avoiding |
Worth mentioning that this problem breaks/contradicts the Do's and Don'ts section on return types of callbacks. |
@HoldYourWaffle
I'm not sure it's in contradiction. That's guidance for callbacks whose value will be ignored. But this is a callback whose value won't be ignored. But Another few solutions to the original problem:
|
Suggestion
π Search Terms
void, async, second-order functions
β Viability Checklist
My suggestion meets these guidelines:
β Suggestion (and motivating example)
(I apologize if there is already discussion around this; I haven't been able to find it.)
It is sometimes convenient for a second-order function to receive a function that may or may not be asynchronous:
Unfortunately
() => void | Promise<void>
seems to cancel TS's normal type inference around() => void
:In addition (this is probably the root cause):
() => Promise<void>
by itself is pickier than I would expect since only() => Promise<undefined>
and() => Promise<any>
are assignable to it. I understand thatvoid
is not an inferrable type but this case does not requirevoid
to be inferred, does it?I suspect this problem exists because of how
void
interacts with parameterized types. Maybe there isn't a general solution to that, but at least I think() => Promise<2> extends () => Promise<void>
would be desirable to support as a special case, given the ubiquity of theasync/await
pattern.π» Use Cases
In my case, I'm writing an implementation of forEach. It is a context that applies backpressure so I want the first-order function to be able to return a Promise, but otherwise I don't care about the output.
() => any
does suffice here;() => any | Promise<any>
is marginally more expressive, although from a type perspective it is exactly the same. In either case I am exposed to the pitfalls of theany
type, in particular that is easy to assign such output to a value by mistake (precisely whatvoid
exists to prevent you from doing).The text was updated successfully, but these errors were encountered: