I have a type alias Data which is a union of two data structure -- one contain array that is not empty while the other is empty:
const dataEmptyArray = { data: [] }
const dataNotEmptyArray = { data: [1, 2, 3] }
type DataEmptyArray = typeof dataEmptyArray
type DataNotEmptyArray = typeof dataNotEmptyArray
type Data = DataNotEmptyArray | DataEmptyArray // <--- union here
function foo(arg:Data) {
if (arg && arg.data && Array.isArray(arg.data)) {
return arg.data.map( (d:(never|number)) => d)
// ^^^<--------- this expression is not callable
} else {
return 'no data'
}
}
const result = foo(dataEmptyArray)
However, when I try to call Array.prototype.map() on the array I have an error said: "this expression is not callable"
The above snippet can be found here
I notice, I can eliminate the type error if I define the alias of Data as intersection:
type Data = DataNotEmptyArray & DataEmptyArray
or simply don't union with DataEmptyArray
type Data = DataNotEmptyArray
Could you please explain why union with empty Array is a problem ? What does it mean when it said "the expression is not callable"? thanks!!
Update typescript to 4.2+ (I recommend the latest version)
This will work for .map, but it will not work for .reduce, .every, .find and .filter
(Edit 2023-05-17: .every, .find and .filter should be fixed in the next release TypeScript 5.2?)
As of May 2023 there is an open issue about the .reduce case:
https://github.com/microsoft/TypeScript/issues/44063
In the meantime you can add as any[] to get rid of the error:
For .map:
const arr: number[] | string[] = [];
// Add as any[]
(arr as any[]).map((a: number | string, index: number) => {
return index
});
For .reduce:
const arr: number[] | string[] = [];
// Add as any[]
(arr as any[]).reduce((acc: number | string, val: number|string) => {
return `${acc} ${val}`
},'');
The issue for .map:
https://github.com/microsoft/TypeScript/issues/36390
The issue for the .every, .find and .filter cases:
https://github.com/microsoft/TypeScript/issues/44373
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With