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
A not-uncommon JS idiom is [].concat(x || [], y || [], z || []) as a faster, simpler, more backwards-compatible [x, y, z].flatMap(x => x || []). However, when I try, I get type errors.
🔎 Search Terms
array concat
concat overload
🕗 Version & Regression Information
This is the behavior in every version I tried, and I reviewed the FAQ for entries about array concat
No overload matches this call.
Overload 1 of 2, '(...items: ConcatArray<never>[]): never[]', gave the following error.
Argument of type 'never[] | "a"' is not assignable to parameter of type 'ConcatArray<never>'.
Type 'string' is not assignable to type 'ConcatArray<never>'.
Overload 2 of 2, '(...items: ConcatArray<never>[]): never[]', gave the following error.
Argument of type 'never[] | "a"' is not assignable to parameter of type 'ConcatArray<never>'.
Type 'string' is not assignable to type 'ConcatArray<never>'.(2769)
🙂 Expected behavior
No type errors (except perhaps that the variable may be any until i provide an explicit type for the resulting array), because this is valid JavaScript since at least ES3.
Bruce Pascoe (@fatcerberus) The examples don't work with strictNullChecks enabled. The playground strangely turns this flag off when you switch to JS mode, I fell for it the first time as well.
Also, spread has different semantics - a string is spread into code units, a Map into entries, a Set into values, but the precise semantic I want here is IsConcatSpreadable, which only concat, flat, and flatMap have.
Activity
ajafff commentedon Jan 8, 2022
As a workaround you can use
new Array<string>().concat( true ? 'a' : [], false ? 'b' : [])ljharb commentedon Jan 8, 2022
That would create a sparse array, which is deoptimized in engines, so that would never be a good workaround (new Array should never, ever be used).
MartinJohns commentedon Jan 8, 2022
([] as string[])works as well to help the type-checker.MartinJohns commentedon Jan 8, 2022
Duplicate of #36554 (comment). Used search terms:
never array concatljharb commentedon Jan 8, 2022
Thanks for the workaround suggestion! Unfortunately that doesn’t help me in JS, using JSDoc.
fatcerberus commentedon Jan 8, 2022
Your examples work as-is for me in JS, even with
checkJson; that said, the equivalent JSDoc-based workaround would beBut this won't work in a
.tsfile (or your playground) because JSDoc isn't used for typing there.MartinJohns commentedon Jan 8, 2022
Bruce Pascoe (@fatcerberus) The examples don't work with
strictNullChecksenabled. The playground strangely turns this flag off when you switch to JS mode, I fell for it the first time as well.SancheZz commentedon Jan 9, 2022
Jordan Harband (@ljharb) you can use
spreadoperator instead of theconcatmethod as a workaround.MartinJohns commentedon Jan 9, 2022
SancheZz He's intentionally not using the spread operator. See his first sentence, where he mentions:
ljharb commentedon Jan 9, 2022
Also, spread has different semantics - a string is spread into code units, a Map into entries, a Set into values, but the precise semantic I want here is
IsConcatSpreadable, which only concat, flat, and flatMap have.