You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Type inference for object literals with string types and Object.assign #17943
This code will not compile, because the type inference for the literal {type: 'abc'} ends when being passed to a function call and the type is inferred as {type: string}, which is of course not assignable to {type: 'abc'}, which is a good thing.
Expected behavior:
I expect the literal to instead be inferred as {type: 'abc'}, so the object can be assigned.
Actual behavior:
The literal is inferred as {type: string}, so assignment cannot be done.
Rationale:
Literal types like 'foo' and 3 are narrower types than string and number, so better type checking can be done with those types. If TypeScript can infer narrower types where possible, then assignments like the above will work.
There is a problem with assignments like the following, however.
If TypeScript were to start inferring {type: 'abc'} in these cases instead of {type: string}, then this could break existing code. So this isn't an easy issue to handle.
Yes, that will also work in this case. In my case, I had some existing objects that weren't tagged, and I had some new types where I was creating objects which have tags in them. So the arguments were [{type: 'abc'}, T] producing T & {type: 'abc'}.
I'm wondering if it would be possible to have TypeScript figure out these kinds of expressions automatically. It certainly wouldn't be easy. It might be impossible.
Yeah it would be great if TypeScript allowed you to annotate an object literal in a way that allowed it to choose the narrowest type possible so you don't have to repeat yourself. Here's something I sometimes use (as a library) when repeating myself feels worse than jumping through hoops:
it becomes a chicken-and-egg problem, since the compiler needs to know the types of the inputs to find the return type, but the return type is what provides the contextual type to inform the inference.
related to #11152
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.
Activity
w0rp commentedon Aug 21, 2017
There is a way to work around this in some cases. You can replace
{type: 'abc'}with{type: 'abc'} as {type: 'abc'}, or write some wrapper functions.kitsonk commentedon Aug 21, 2017
Or this:
This is expressly what type coercion is designed for, for dealing with situations where narrower types cannot be reliably contextually inferred.
w0rp commentedon Aug 21, 2017
Yes, that will also work in this case. In my case, I had some existing objects that weren't tagged, and I had some new types where I was creating objects which have tags in them. So the arguments were
[{type: 'abc'}, T]producingT & {type: 'abc'}.I'm wondering if it would be possible to have TypeScript figure out these kinds of expressions automatically. It certainly wouldn't be easy. It might be impossible.
jcalz commentedon Aug 21, 2017
Yeah it would be great if TypeScript allowed you to annotate an object literal in a way that allowed it to choose the narrowest type possible so you don't have to repeat yourself. Here's something I sometimes use (as a library) when repeating myself feels worse than jumping through hoops:
You'd use it like this:
Ugly and obnoxious, but it does infer the literals.
mhegazy commentedon Aug 21, 2017
it becomes a chicken-and-egg problem, since the compiler needs to know the types of the inputs to find the return type, but the return type is what provides the contextual type to inform the inference.
related to #11152
mhegazy commentedon Sep 6, 2017
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.