-
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-like recursive generic interface invariant in its parameter type #35805
Comments
@ahejlsberg thoughts? |
First off, looks like we measure declare const fn: Fn<string, number>;
// Invariant in A
const fn1: Fn<unknown, number> = fn; // Error
const fn2: Fn<'a', number> = fn; // Error
// Covariant in B
const fn3: Fn<string, unknown> = fn; // Ok
const fn4: Fn<string, 0> = fn; // Error This is pretty much the expected result. As we attempt to relate the recursive references to We could consider variance annotations, but we would then also need logic to verify that type declarations don't violate them. |
Oops, I got my variance backwards in the example code... I'll update it Edit: all right, I updated it. |
See #36261 for an improved method of measuring variance. |
I'm aware that this is likely to be a design limitation; I can't find an existing issue about this specific problem so I'm filing this one for reference.
TypeScript Version: 3.8.0-dev.20191220
Search Terms: variance, composition
Code
Expected behavior:
Fn<A, B>
should be contravariant inA
.Actual behavior:
Fn<A, B>
is invariant inA
.I came upon this while investigating a Stack Overflow question in which someone had built a composable type like
Fn<A, B>
and had to use a workaround to allow thethen()
method to accept something with a wider input.@jack-williams suggests that the issue happens because the checker defaults to covariance for
A
when checking it (intypeArgumentsRelatedTo()
)... and combined with its contravariant use in the call signature, this results in invariance.A full structural check might not have this problem but I imagine it might be hard to guarantee that such a check would terminate? (e.g.,
Fn<A, B>
depends onFn<B, C>
which depends onFn<C, D>
which depends onFn<D, E>
etc?)If there's no plausible way for the compiler to correctly infer the variance here, perhaps this is just another request for variance annotations as per #1394?
Not sure. Anyway, thanks!
Playground Link: Provided
Related Issues:
#1394: let us mark the parameters as covariant/contravariant/invariant ourselves
#32674: a different variance issue
#33872: a different variance bug
The text was updated successfully, but these errors were encountered: