TypeScript Version: 3.5.0-dev.20190511
Code
[0].concat('')
// Argument of type '""' is not assignable to parameter of type 'number | ConcatArray<number>'.
Expected behavior:
The concated array has type (number|string)[].
Actual behavior:
Error.
Possible fix:
In https://github.com/microsoft/TypeScript/blob/b7fe99a88c59bd652029bdfe5b6ba8709a677838/lib/lib.es5.d.ts#L1231
interface Array<T> {
- concat(...items: ConcatArray<T>[]): T[];
+ concat<U>(...items: ConcatArray<U>[]): (T|U)[];
Playground Link:
https://www.typescriptlang.org/play/#src=%5B0%5D.concat(%5B''%5D)
Related Issues:
Search Terms:
array concat
You can always use declaration merging to add a generic overload to Array.concat() if you find it useful in your own code:
// declaration merge
interface Array<T> {
concat<U>(...items: (U | ConcatArray<U>)[]): (T | U)[]
}
const okay = [0].concat(""); // Array<string | number>
Or, you can widen the array element type yourself before concating to it:
const okay = [0 as string | number].concat(''); // Array<string | number>
Before the standard library is modified for everyone, though, you'd want to establish that this use case is common enough in real-world code to warrant it. The compiler tries to catch potential bugs. For real uses of concat() in the wild, what is the false-positive (the compiler thinks good code is a bug) rate of the current typings, and how does that compare to the false-negative (the compiler doesn't catch a bug) rate of the proposed typings?
Duplicate #26378
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.
I have hit this issue while developing a Vue.js component that accepts a value property which can be of type string | string[] | number | number[].
It is an option-list type component that allows a user to select either a single or multiple options from a given list, the options being indexed by string or number ids. The reason I'm not only accepting arrays as the value prop is that the component is bound directly to my form model, which is in turn created automatically from the view model, so keeping proper value type was a requirement.
Within the component however, it is handy to always work with the prop as an array, so I created a simple getter using the `[].concat()' trick. No biggie in vanilla JS but turned out to be an issue with TS. I have dealt with it like so:
get valueArray(): string[] | number[] {
return ([] as (string | number)[]).concat(this.value || []) as string[] | number[];
}
Most helpful comment
I have hit this issue while developing a Vue.js component that accepts a
valueproperty which can be of typestring | string[] | number | number[].It is an option-list type component that allows a user to select either a single or multiple options from a given list, the options being indexed by string or number ids. The reason I'm not only accepting arrays as the
valueprop is that the component is bound directly to my form model, which is in turn created automatically from the view model, so keeping proper value type was a requirement.Within the component however, it is handy to always work with the prop as an array, so I created a simple getter using the `[].concat()' trick. No biggie in vanilla JS but turned out to be an issue with TS. I have dealt with it like so: