typescript, Array.prototype.map() har felet 'expression is not callable' när den kallade arrayen är en union med en tom array
Jag har en typalias Data som är en union av två datastrukturer -- ena innehåller en array som inte är tom medan den andra är tom:
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)
Men när jag försöker anropa Array.prototype.map() på arrayen får jag ett felmeddelande som säger: "detta uttryck kan inte anropas"
Ovanstående utdrag kan hittas här
Jag märker att jag kan eliminera typfelet om jag definierar aliaset för Data som snitt:
type Data = DataNotEmptyArray & DataEmptyArray
eller helt enkelt inte förena med DataEmptyArray
type Data = DataNotEmptyArray
Kan du vänligen förklara varför union med en tom Array är ett problem? Vad betyder det när det står "uttrycket är inte anropbart"? Tack!!
Svar #1
Alternativ 1
Uppdatera TypeScript till 4.2+ (Jag rekommenderar den senaste versionen)
Detta kommer att fungera för .map, men det kommer inte att fungera för .reduce, .every, .find och .filter
(Redigera 2023-05-17: .every, .find och .filter bör åtgärdas i nästa release TypeScript 5.2?)
Från och med maj 2023 finns det ett öppet ärende om .reduce-fallet: https://github.com/microsoft/TypeScript/issues/44063
Alternativ 2
Under tiden kan du lägga till as any[] för att bli av med felet:
För .map:
const arr: number[] | string[] = [];
// Add as any[]
(arr as any[]).map((a: number | string, index: number) => {
return index
});
För .reduce:
const arr: number[] | string[] = [];
// Add as any[]
(arr as any[]).reduce((acc: number | string, val: number|string) => {
return `${acc} ${val}`
},'');
Mer information
Problemet för .map:
https://github.com/microsoft/TypeScript/issues/36390
Problemet för .every, .find och .filter-fallen:
https://github.com/microsoft/TypeScript/issues/44373
