-
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
Generic parameter implicitly broadens object key to string. #55110
Comments
As always, #55060 (comment) is relevant here. The casted function claims to return const entryName = 0.5 > Math.random() ? "foo" : "bar";
const casted = createMapWithCast(entryName, 3);
const inline = {
[entryName]: 3,
} as const;
type Casted = typeof casted;
// ^? { readonly foo: 3, readonly bar: 3 } - but you really only have one of them!
type Inline = typeof inline;
// ^? { readonly [x: string]: 3 } The return type of a function, even a generic one, is inferred from the function body. Because |
See also: #27808. |
Thanks for the clarification that the 'literal' nature of the value isn't carried by any type information, and so has to be considered to be potentially broad. So I gather from the discussion that there is currently no way to flag that a narrowed literal is required, or to implicitly benefit from the case when N is not a union, (e.g. is known by code path to be a single value and therefore can be kept narrow throughout?). Imaginary case below...
The above pseudo-code would be a compile error if Is tracing actual literals through code paths an impossible feature to consider or did I miss something important? Seems like it would have power, and for a lot of authored structures, things begin as literals, (from which inference is intended) and for others perhaps guard functions could facilitate. |
Yeah, basically there's no type you can currently write in place of
That would be #27808, more or less. Control flow analysis doesn't enter function calls (n.b. spiel above about function return types), so the way forward on this would be an annotation on the type parameter itself that explicitly prevents it from being instantiated as a union type in the first place. Beyond that, no additional "tracking" should be needed, as TS already has literal types. For the record, your current |
This issue has been marked as "Working as Intended" and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
Bug Report
Const object having typed string keys should not be broadened to string when key is an inferred const function parameter and type is a const object.
In the example below
SingleEntryCreated
is the type at fault and it has[x:string]
where it should have"iamanentry"
.In the createMapWithCast factory function below, there should not be a need to cast with
as Readonly<{[k in N]:V}>
as it is already known to be exactly that. All three types of singleEntryCreated, singleEntryCreatedWithCast, singleEntryInline should have identical type.🔎 Search Terms
Object key type broadened narrowed.
🕗 Version & Regression Information
⏯ Playground Link
Playground link with relevant code
💻 Code
🙁 Actual behavior
Embedding the construction of an object inside a factory (passing a string key for inference) has the key broadened to string.
🙂 Expected behavior
The key should not be broadened to string as it is known to be exactly the inferred generic value.
The text was updated successfully, but these errors were encountered: