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
"Target requires x element(s) but source may have fewer." despite filter by lengthΒ #62422
Type 'string[][]' is not assignable to type '[string, string, string][]'.
Type 'string[]' is not assignable to type '[string, string, string]'.
Target requires 3 element(s) but source may have fewer.
TS does not treat checking length as a type guard on array types that aren't already (unions of) tuples. This isn't a bug; everything is behaving as intended and as designed. It's more of a limitation or missing feature. Maybe it's a duplicate of #28337.
As a workaround you can always tell TS that x => x.length == 3 behaves as a type guard, like so:
arr.map(x=>x.split("")).filter((x): x is [string,string,string]=>x.length==3);
We don't really have a good way to implement this. Even intersecting in a { length: 3 } property (which even by itself is suspect in terms of downstream effects), that's not enough to turn a string[] into a [string, string, string]
The point wasn't to code-golf, it was to show how you could tell TS that the filter callback was meant to act as a type guard, without changing the emitted JS at all.
We're not really willing to add special-case magic like that to the type system. If something can't be implemented in a way that's general-purpose, it's generally not done at all
Activity
jcalz commentedon Sep 9, 2025
note: not a TS team member, ignore me if you want
TS does not treat checking
lengthas a type guard on array types that aren't already (unions of) tuples. This isn't a bug; everything is behaving as intended and as designed. It's more of a limitation or missing feature. Maybe it's a duplicate of #28337.As a workaround you can always tell TS that
x => x.length == 3behaves as a type guard, like so:Playground link
Sainan commentedon Sep 9, 2025
Well, it can be done shorter :^)
Playground link
But the point is that this is unexpected. It's not like a major issue, but definitely something that "could be improved."
RyanCavanaugh commentedon Sep 9, 2025
We don't really have a good way to implement this. Even intersecting in a
{ length: 3 }property (which even by itself is suspect in terms of downstream effects), that's not enough to turn astring[]into a[string, string, string]jcalz commentedon Sep 9, 2025
The point wasn't to code-golf, it was to show how you could tell TS that the filter callback was meant to act as a type guard, without changing the emitted JS at all.
Sainan commentedon Sep 9, 2025
I know. My point was just to show that
.mapcan help it see the type conversion since indexing astring[]is seen as producingstringby default.typescript-bot commentedon Sep 12, 2025
This issue has been marked as "Design Limitation" and has seen no recent activity. It has been automatically closed for house-keeping purposes.
Sainan commentedon Sep 12, 2025
Can
.filter(x => x.length == 3)really not be implied to be the same as.map(x => [ x[0], x[1], x[2] ])?RyanCavanaugh commentedon Sep 12, 2025
We're not really willing to add special-case magic like that to the type system. If something can't be implemented in a way that's general-purpose, it's generally not done at all