-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Couple apparent bugs with variance checking #53210
Comments
Came here to report that the type F<out A, out B> = <X>(v: X extends A ? X : never) => B
const a: F<never, never> = v => v
const b: F<number, never> = a
const result: never = b(42) // whoops |
@nightlyherb Hmm, not sure I'm following. The The snippet you gave also contains an |
I just tried to say that all the examples you gave and the example I gave exhibits buggy behavior with or without variance annotations. The buggy behavior without variance annotations might be a separate issue, but I thought it was worth a mention since it's so similar and it might be a related issue. |
@nightlyherb You're right that the issues are related, in fact I think they're mostly indistinguishable. The buggy behavior we're talking about is the ability to assign |
A type parameter appearing only in a constraint is kinda sus, and generally you would want to write // Incorrect: Fails to error
type F1<out A> = <X>(v: X & A) => unknown;
// Correctly errors
type F2<out A> = <X>(v1: X, v2: A) => unknown;
// Correctly errors
type F3<out A> = <X>(v2: A) => X; |
I have encountered a situation where this sus usage could be useful. // F seems to behave like a generic type contravariant over Xi,
// but typescript doesn't error on either in Xi or out Xi,
// so I cannot use this generic type.
type F<Xi> = <X extends Xi>(x: X) => X;
// I can instantiate this generic type manually
// to observe the contravariant behavior.
// number is a subtype of unknown and
// F<unknown> seems to be a subtype of F<number>
declare const funknown = <X extends unknown>(x: X) => X;
declare const fnumber = <X extends number>(x: X) => X;
const funknown2: typeof funknown = fnumber; // error
const fnumber2: typeof fnumber = funknown; // no error
// this does seem natural because `funknown` is assignable
// to a superset of types assignable from `fnumber` May I ask, is my observation correct? |
Bug Report
🔎 Search Terms
variance, methods, generics
NB: I did not search very exhaustively, but I did minimize the examples, so should be pretty easy to review and close as dupe or "by design" or whatever.
🕗 Version & Regression Information
strictFunctionTypes
⏯ Playground Link
Variance checking does not interact correctly with
extends
:https://www.typescriptlang.org/play?#code/C4TwDgpgBAYgPAewK7CgQQDRWagQgPigF4o4ANKCAD2AgDsATAZ3WPXwAoA3ALijICUxQrgBQogMYI6TVAEM+8OhC4QATlmWq1hEl2FQuk6bKgAjRXDpIAtmfWaV63VDnGZqNRCZIANsD4tdTYzDgAWACYhAHpoqAB3AAsEBDAmIA
Variance checking does not interact correctly with "records with methods" types:
https://www.typescriptlang.org/play?#code/C4TwDgpgBAGgPAewK7CgZQHxQLxQN4BQUUAHgBQDOAXOgJQ0B2EAbhAE4EC+BBAxggwqoAhjXhNWbLLjykaFHFgXd+g1ACMxcJAwDWDBAHcG0qML4ChUQwAsECMNSgT2OKOoB05ACwAmWgRAA
💻 Code
Variance checking does not interact correctly with
extends
:Variance checking does not interact correctly with "records with methods" types:
🙁 Actual behavior
In both cases the typechecker allows me to inhabit
never
.🙂 Expected behavior
The typechecker should reject my incorrect variance annotations (
F<out A, ...>
andX<out S>
) and not allow me to inhabitnever
.Incidentally this came to light out of some discussion in the "forall for non-functions" issue here: #17574 (comment), but these things don't really seem materially related.
Related to #48240.
The text was updated successfully, but these errors were encountered: