Closed
Description
Version 2.0.2
type A = 'a'
const z: A[] = ['a']; // fine as expected
// how come 'a' cannot be inferred as type `A`?
const x: A[] = Array.from(['a']) // Error: Type 'string' not assignable to 'a'
// my workaround (without creating a variable):
const y: A[] = Array.from([_.identity<A>('a')])
I think this may be related to #10676
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
mhegazy commentedon Sep 2, 2016
The main problem is that literal types are not inferred unless there is a contextual type. and for generic types, return types are not an inference position. so the
A[]
inconst x: A[] = Array.from(['a'])
does not impact howT
is inferred forArray.from
call. and thus"a"
is always inferred asstring
.The rational here is that literal types were added later on, and inferring them always by default would be a breaking change to code written before TS 1.8. e.g.:
Now #10676 is trying to address that by inferring literals more often. but it will not address all cases, such as the one above. you can see the description @ahejlsberg provides in the PR:
The rational here is that a literal type is not super useful by itself, if the target of the inference is not one itself. e.g.
new Array('a')
, most likely you do not want an array ofa
's, but rather a string array with one initial value.so to an extent this issue is really a design limitation. if we infer literal types all the time, this breaks existing code in a huge way.
A better work around for this scenario is to explicitly specify the generic type argument for
Array.from
, e.g: