Closed
Description
Bug Report
π Search Terms
function overload signature void promise
π Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about overloads
β― Playground Link
Playground link with relevant code
π» Code
declare const it: {
(callback: () => void): void;
(callback: () => Promise<void>): void;
};
it(async () => { });
π Actual behavior
Autocomplete and hover show the first matching signature:
(callback: () => void): void;
π Expected behavior
I would have hoped for the more precise signature:
(callback: () => Promise<void>): void;
More (Downstream) Details
This actually causes some issues in typescript-eslint's no-misused-promises
rule. See typescript-eslint/typescript-eslint#4620:
- When someone calls
it(
like above, we'd want to be able to check the precise resolved signature for the call to know whether they're dangerously passing a() => Promise<void>
to an argument that takes() => void
- The type checker
getResolvedSignature
API returns the() => void
overload instead first - That overload would make calls that provide
() => Promise<void>
seem unsafe
Our workaround is to check all call signatures, which is imprecise and can lead to false negatives in cases like:
declare const it: {
(syncName: string, callback: () => void): void;
(asyncName: number, callback: () => Promise<void>): void;
};
// We'll see that an overload exists that has callback: () => Promise<void>.
// Without knowing it's the specific resolved one for this call,
// we'll consider the call safe (even though it's not)
it('', async () => { });
See standalone repro here: https://github.com/JoshuaKGoldberg/repros/tree/typescript-promise-returning-overload-resolve
I think this is different from #41563 because this issue also repros in 4.1.0-beta.
Metadata
Metadata
Assignees
Labels
No labels