-
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
Non-widening explicit literal types #11126
Conversation
Is that gonna be a two separate kinds of literal types? would this type flow through? function f<T>(value: T): T { return value; }
const a1: "a" = "a";
const a2 = "a"; // widening "a"
let v1 = f(a1); // "a" ?
let v2 = f(a2); // string ?
const c3 =f(a2); // widening "a" ? |
@Igorbek Yes, the widening and non-widening literal types for a particular literal are distinct types. Your example behaves as you expected: function f<T>(value: T): T { return value; }
const a1: "a" = "a"; // "a"
const a2 = "a"; // widening "a"
let v1 = f(a1); // "a"
let v2 = f(a2); // string
const c3 = f(a2); // widening "a" |
@ahejlsberg thanks so much for taking my feedback into consideration. I'm glad my proposal proved more-or-less tractable, and after a bit of a scare in our codebase, I'm looking forward to continuing to use improved literal types in Glimmer. I want to add that I really appreciate the stewardship of the TypeScript project, both in efforts to explain the rationale for changes and taking considered feedback into consideration in response to those rationales. All in all, this back-and-forth was pretty healthy, and a good example of what I like about the project. 😄 |
This PR expands upon #10676 by making explicitly denoted literal types non-widening. String and numeric literal types now come in two flavors: Widening and non-widening. The two flavors are completely interchangeable in type relationships and control flow type analysis, but only one widens to the base primitive type when inferred as the type for a mutable location:
The net effect of this change is that literal type widening can be controlled through explicit type annotations. Specifically, when an expression of a literal type is inferred for a
const
location without a type annotation, thatconst
variable gets a widening literal type inferred. But when aconst
location has an explicit literal type annotation, theconst
variable gets a non-widening literal type.The flavor of a literal type is preserved in union types, but the widening form disappears if the union also contains the non-widening form. Effectively, the non-widening form is given preference.
Fixes #10898.