-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Function overloading breaks type parameter inference for higher-order function #31829
Comments
This is effectively a design limitation. During overload resolution the checker has to resolve the types of the I suggest reversing the overloads. It works once you do. |
Ah I see. It makes sense it wouldn't work then. It's odd that the behavior changes depending on the order of the overloads, but to be honest I didn't think TypeScript would be able to handle this situation at all, so I have to give it props for that. |
@ahejlsberg I'd be interested in knowing if the same design limitation that you describe above applies to another case that I'm working on below, or if it might be a different issue: The main idea is that I'm trying to say "If the type parameter's properties are all optional, then the function's parameter is optional. If the type parameter has required properties, then the function's parameter is required." And the code below does essentially accomplish that idea, but my complaint is that the error message As far as I can tell, the problem comes from how TS resolves to the first overload based on the absent function parameter, when really I wish that it could resolve to the second overload based on the type parameter. Searching for this led me here, and your comments about overload resolution made me wonder if this is a result of the same design limitation or not. declare namespace Test {
type EmptyObject<T> = {} extends T ? {} : never
interface Thing {
new <T extends EmptyObject<T>>(params?: T): void
new <T extends object>(params: T): void
}
const Thing: Thing
}
new Test.Thing<{ optional?: number }>() // Optional case - works fine
new Test.Thing<{ optional?: number }>({ optional: 123 }) // Optional case - works fine
new Test.Thing<{ required: string }>({ required: 'hello' }) // Required case - works fine
new Test.Thing<{ required: string }>() // Required case - errors, as expected...although the error is extremely confusing |
TypeScript Version: 3.5.1, 3.6.0-dev.20190608, 3.4
Search Terms:
compose, generic unknown, overloaded generic type inference
Code
Expected behavior:
S
should be inferred to bestring
, just like it is without the additional parameter to the first overload ofpipe
. Or maybe inference should totally fail. But the presence of the extra argument should not change what happens, since overload resolution doesn't seem to be ambiguous here.Actual behavior:
S
is inferred to beunknown
, but only in the presence of the extra argument to the first overload. If you remove it, it works perfectly.Playground Link
The playground uses an older version of tsc, so here
x
is inferred to be{}
instead.Related Issues:
This - #31738
The text was updated successfully, but these errors were encountered: