打字稿,当被调用者数组与空数组联合时,Array.prototype.map() 有错误“表达式不可调用”

apo*_*llo 11 typescript

我有一个类型别名Data,它是两个数据结构的联合——一个包含非空的数组,而另一个为空:

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)
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试在数组上调用 Array.prototype.map() 时,出现错误提示:“此表达式不可调用”

上面的代码片段可以在这里找到

我注意到,如果我将 Data 的别名定义为交集,我可以消除类型错误:

type Data = DataNotEmptyArray & DataEmptyArray
Run Code Online (Sandbox Code Playgroud)

或者干脆不与 DataEmptyArray

type Data = DataNotEmptyArray
Run Code Online (Sandbox Code Playgroud)

你能解释一下为什么与空数组联合是一个问题吗?当它说“表达式不可调用”时是什么意思?谢谢!!

saz*_*y4o 22

选项1

typescript更新到4.2+(我推荐最新版本)

这适用于.map,但不适用于.reduce

截至 2021 年 7 月,该.reduce案例存在一个未解决的问题:https : //github.com/microsoft/TypeScript/issues/44063

选项 2

同时,您可以添加as any[]以消除错误:
对于.map

const arr: number[] | string[] = [];
// Add as any[]
(arr as any[]).map((a: number | string, index: number) => { 
    return index
});
Run Code Online (Sandbox Code Playgroud)

对于.reduce

const arr: number[] | string[] = [];
// Add as any[]
(arr as any[]).reduce((acc: number | string, val: number|string) => { 
    return `${acc} ${val}`
},'');
Run Code Online (Sandbox Code Playgroud)

更多信息

有关更多信息,请参阅原始 Github 问题:https : //github.com/microsoft/TypeScript/issues/36390

  • 选项 2 效果很好!谢谢你! (2认同)