Repository navigation
TS ^4 does not recognize array methods on (T[] | T[][]) as callable #40157
Description
Activity
The error disappears if the array is initialized with something inside.
const a: string[] | string[][] = []; a.every(() => {}); // TS-2349: This expression is not callable. const b: string[] | string[][] = [[]]; b.every(() => {}); // ok const c: string[] | string[][] = ['c']; c.every(() => {}); // ok const f = (d: string[] | string[][]) => { d.every(() => {}); // TS-2349: This expression is not callable. }
Reacted by Dmitry BelyaevMethods, that do not have generic overloads (
some,forEach) are not affected.- addedNeeds InvestigationThis issue needs a team member to investigate its status.This issue needs a team member to investigate its status.
on Aug 20, 2020 This is working as intended (or at least a current design limitation), if a breaking change in 4.0 due to a
libupdate - #38200 added a second, generic overload to.every, making it so we couldn't resolve a single combined signature for the union (and so it now behaves as.mapand friends).Changing the types you annotate on the argument to
.everyaren't going to make.everyitself callable. The issue is that the union of the two array types contains irreconcilable overload lists for.every(we'd have to create a power set of signatures and resolve them as a new overload list, while also unifying generics in similar positions, and even then it's not necessarily correct) - you need to cast the.everycall itself (which is going to break any type guards you try to apply, mind you).- addedBreaking ChangeWould introduce errors in existing codeWould introduce errors in existing codeWorking as IntendedThe behavior described is the intended behavior; this is not a bugThe behavior described is the intended behavior; this is not a bugand removedNeeds InvestigationThis issue needs a team member to investigate its status.This issue needs a team member to investigate its status.
on Aug 20, 2020 Ryan Cavanaugh (@RyanCavanaugh) up to you - this break should possibly be noted in the release breaking changes, if we want to keep it (otherwise we'd revert #38200 and unfix its associated issue).
So is there currently any proper workaround? I can't seem to get around the error.
Pleun Vanderbauwhede (@pleunv)
If introducing runtime typeguard is acceptable (in my case - it is), you could go with something along the lines of:
const isArrayOfArrays = (candidate: unknown[]): candidate is unknown[][] => { // you might want to add special case for an empty candidate - this implementation returns `true` return candidate.every(Array.isArray); } const f = (a: string[] | string[][]) => { const g = (b: string | string[]) => { // ... } if(isArrayOfArrays(a)) { a.every(g); } else { a.every(g); } }
typescript-bot commented
on Aug 23, 2020 ContributorMore actionsThis issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.
- locked as resolved and limited conversation to collaborators
on Oct 21, 2025
TypeScript Version: 4.0.2, 4.1.0-dev.20200820
Search Terms: union, array methods
Code
The following example uses
everymethod, but the bug affects all other methods as well (map,reduce, etc.).Expected behavior: No errors, code should compile.
Actual behavior: Error
TS-2349: This expression is not callable.Playground Link: https://www.typescriptlang.org/play?ts=4.1.0-dev.20200819#code/MYewdgzgLgBAhgLhtATgSzAcwNoF0YA+yU6WeeMAvDHgNwBQ9cAdAKYBurKAngBQBGVAHwxQkEABtWzCSEwCAlAoZM2nHrwFJUGTIWKkcuBcNHgIk6bPn8lKlhy58tB3fp1ljSQWgiusplDcAA6sIABmMIKUMTAA5B6Yccr0QA
Related Issues: I didn't find anything similar.