typescript,Array.prototype.map()在被调用方数组与空数组联合时出现错误'表达式不可调用'

问题描述 投票:1回答:1

我有一个类型别名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)

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

上面的代码片段可以找到here

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

type Data = DataNotEmptyArray & DataEmptyArray

或干脆不与DataEmptyArray结合

type Data = DataNotEmptyArray

您能否解释为什么与空Array合并是一个问题?说“表达式不可调用”是什么意思?谢谢!!

typescript
1个回答
0
投票

问题不是真正的空数组。如果您遇到2个数组具有不同类型的情况,例如if带数字和字符串的数组

const dataEmptyArray = { data: ['my string'] };
const dataNotEmptyArray = { data: [1, 2, 3] };

这被视为TS的限制,对于您的案例string[] | number[],他将无法处理联合类型never[]|number[]。他不会假设是Array,如果您强制转换为Array,则可以调用该地图。

也在github https://github.com/microsoft/TypeScript/issues/33591上提出了提出的问题>

我们没有任何方法可以根据分析时间进行适当的检查。(...)

正确检查该程序的唯一方法是将内部主体的主体重新检查3 * 3 * 3次(!),并且TS在每次调用时都需要清除其表达式类型的缓存(当前在架构上是不可能的)。甚至不清楚我们在这里将显示arr的类型!

© www.soinside.com 2019 - 2024. All rights reserved.