-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
InstanceType
and constructor return type inference doesn’t work for built‑in subtypes of ErrorConstructor
#61460
Comments
Here's a generalized example of the relevant type system behavior. The difference between the built-in error constructor types and your custom one is that the built-in ones inherit from These types are all structurally-identical though so arguably none of this behavior is "wrong" (but it does lead to non-ideal type info). |
Changing the type OmitCallSignatures<T> = { [K in keyof T]: T[K] };
interface TypeErrorConstructor extends OmitCallSignatures<ErrorConstructor> {
} would fix this specific issue, as the static side also inherits the call signatures by default. I would expect that subinterface new/call signatures would take priority over superinterface new/call signatures in |
This is a weird interaction between overload resolution and If you have two interfaces interface Base {
(): string;
}
interface Derived extends Base {
(): "derived";
} then we merge the overloads with the derived class first: (): "derived";
(): string; This is desirable because in a call position
(s: string): number;
(s: number): string;
(s: string | number): string | number; where the last overload is the "catch-all" that has the widest return type. I think the right fix would be to split up interface ErrorConstructorStatics {
// whatever goes here
}
interface ErrorConstructor extends ErrorConstructor {
new(message?: string): Error;
}
interface SpecialErrorConstructor extends ErrorConstructorStatics {
new(): SpecialError;
} this would break existing interface merges on |
One option would be to filter out inherited overloads which are wholly subsumed by overloads declared on the subinterface, e.g.: for: interface ErrorConstructor extends ErrorConstructor {
new (message?: string): Error;
new (message?: string, options?: ErrorOptions): Error;
}
interface SpecialErrorConstructor extends ErrorConstructor {
new (message?: string): SpecialError;
new (message?: string, options?: ErrorOptions): SpecialError;
} Because the Instead of getting a list of overloads for
The list of overloads checked by
|
🔎 Search Terms
🕗 Version & Regression Information
dtslint
only tests back to TypeScript 5.0, and the bug workbench failed to download versions older than TypeScript 4.0.⏯ Playground Link
https://www.typescriptlang.org/dev/bug-workbench/?#code/CYUwxgNghgTiAEkoGdnwMIFdkBcD2AtgKIwx4zwgAeOIAdsGiWRQN4BQAvu+zgJ4AHBADkiARngBeeAEk6uKHTAgAKoJAAeIgDcoEZuXR55OGJjD4YAPgDc7APT34z+AD0A-D35D4ogExSsiaKympCGgBKigDmIAYwRiZmFuS2Dk4uHl7qvkQAzIFyCkqq6pEgAGYgcCXxibjJlmmOLm6evDmiACyFwSVhmgDKfHQ4UFR1xg3mTXYtme3eIkQArL3FoWUDk0kzqXMZzlkdPqIAbOtj-WUAqhEyO9Mp1getx0sYRJchpeFLeBUMNh8MRSPt0m9PEA
💻 Code
Workbench Repro
🙁 Actual behavior
Type query results:
🙂 Expected behavior
Type query results:
Additional information about the issue
Same happens with:
Workbench Repro
Related issues
The text was updated successfully, but these errors were encountered: