我有一个类型别名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合并是一个问题?说“表达式不可调用”是什么意思?谢谢!!
问题不是真正的空数组。如果您遇到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的类型!