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
TS ^4 does not recognize array methods on (T[] | T[][]) as callable #40157
The following example uses every method, but the bug affects all other methods as well (map, reduce, etc.).
consta: string[]|string[][]=[];a.every(b=>console.log(b));// TS-2349: This expression is not callable.// Attempt №1: suppress TS-7006a.every((b: string|string[])=>console.log(b));// TS-2349: This expression is not callable.// Attempt №2: rewrite as typeguard (as in https://github.com/microsoft/TypeScript/blob/v4.0-beta/lib/lib.es5.d.ts#L1319)a.every((b: string|string[]): b is string=>typeofb==='string');// TS-2349: This expression is not callable.
Expected behavior: No errors, code should compile.
Actual behavior: Error TS-2349: This expression is not callable.
The error disappears if the array is initialized with something inside.
consta: string[]|string[][]=[];a.every(()=>{});// TS-2349: This expression is not callable.constb: string[]|string[][]=[[]];b.every(()=>{});// okconstc: string[]|string[][]=['c'];c.every(()=>{});// okconstf=(d: string[]|string[][])=>{d.every(()=>{});// TS-2349: This expression is not callable.}
This is working as intended (or at least a current design limitation), if a breaking change in 4.0 due to a lib update - #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 .map and friends).
Changing the types you annotate on the argument to .every aren't going to make .every itself 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 .every call itself (which is going to break any type guards you try to apply, mind you).
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).
If introducing runtime typeguard is acceptable (in my case - it is), you could go with something along the lines of:
constisArrayOfArrays=(candidate: unknown[]): candidate is unknown[][]=>{// you might want to add special case for an empty candidate - this implementation returns `true`returncandidate.every(Array.isArray);}constf=(a: string[]|string[][])=>{constg=(b: string|string[])=>{// ...}if(isArrayOfArrays(a)){a.every(g);}else{a.every(g);}}
Activity
dkamyshov commentedon Aug 20, 2020
The error disappears if the array is initialized with something inside.
https://www.typescriptlang.org/play?ts=4.1.0-dev.20200819#code/MYewdgzgLgBAhgLhtATgSzAcwNoF0YA+yU6WeeMAvDHgNwBQ9cAdAKYBurKAngBS8BKKgD4YAbwC+AhvVCRYAIySoMOfERVlcFatjy4ZCtpx78hlUZOmM50GMGUlVFDU606aAcmCeDN41x8giLiUjK2sABmVDC8ACaOpGqExEnkuOaW9DA5MHEBpsEWodYS9EA
dkamyshov commentedon Aug 20, 2020
Methods, that do not have generic overloads (
some,forEach) are not affected.weswigham commentedon 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).weswigham commentedon 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).
pleunv commentedon Aug 21, 2020
So is there currently any proper workaround? I can't seem to get around the error.
dkamyshov commentedon Aug 21, 2020
Pleun Vanderbauwhede (@pleunv)
If introducing runtime typeguard is acceptable (in my case - it is), you could go with something along the lines of:
typescript-bot commentedon Aug 23, 2020
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.