-
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
Generic literal marker not obeyed for unknown and {} #32169
Comments
The exact rules we use for widening inference candidates are a bit more complex (see
Primitive types are I'm not sure I see a compelling reason to change these rules, in particular since it would likely break code that depends on the current behavior. |
@ahejlsberg why isn't e.g. widening to At a minimum, I would expect the non-values ( |
The specific code this breaks for us is: function assert<T extends {}|undefined|null>(x: T): NonNullable<T> { ... } This function has the important property that it can be inserted around any expression to get the same result type out: enum E { A, B }
const x = assert(E.A); // type E.A However, you cannot pass (You might wonder why there's any code that ever assert()s on an unknown, because the return type isn't useful. But it still is useful because it throws on null.) This came up in particular in TS3.5, because we are seeing a lot more code that ends up passing around unknowns, due to the default constraint change (#30637). |
So, first of all, in the original example function f<T>(x: T): T { return x; }
enum E { A, B }
let x = f(E.A); // x has type E, not E.A the reason for the widened type is that However, when the example is changed to declare function f<T>(x: T): NonNullable<T>; we start widening because we don't consider the occurrence of
We never updated this rule to account for conditional types. I think we should augment the definition to
That should fix the specific code that is breaking (because the type parameter constraint doesn't even matter then). |
In general, if we're going to keep literal types we should keep them for all types, not just some types. And if the constraint is You could argue that we shouldn't consider |
Changing this to be a bug, the bug being that the check for top-level occurrences of a type parameter should be augmented to handle conditional types as I describe above. |
TypeScript Version: 3.4 up to 3.6-dev20190628
Search Terms:
generic literal unknown
Code
This is expected:
According to #24919 (comment) , you can get this to produce an E.A if you add an extends marker:
Expected behavior:
I'd expect the same literal inference if you write these forms too:
Actual behavior:
It has the other behavior, as if you have no
extends
clausePlayground Link:
http://www.typescriptlang.org/play/#code/FAUwdgrgtgBAojA3jAggGhgIRgX2MAMwjAGMAXASwHswYCBGAHgBUA+ACgA8AuGZgSl7MkMAE4gyEUbU4BuXMAA2EmJ3owAvHXrs4AOhT95MAPQnVMABYBDAM4wyATwAOIePiKlKNOgCYWMCCcZOAAJvaIOAA+kIqKUcShIAQUYCChHDx8gnwi4pLSqvJ4ymSqvpp+ugZGMKbmnFZ2Di5u+igexOTUtAQAzAFBIWDhMMQA1mBUAO5gmUI5wsj5UjLFSiqcfZX91YbGZhY29k6u8DAA-BcAhEA
Related Issues:
The text was updated successfully, but these errors were encountered: