为什么TypeScript声称它是;无法调用其类型缺少调用签名“的表达式”;?
编辑:根据要求,TypeScript版本为3.2.2 关于StackOverflow上的这一特定错误,有很多问题和答案,但没有一个能令人满意地解释发生这种情况的原因 据我所知,如果我有这样的类型:为什么TypeScript声称它是;无法调用其类型缺少调用签名“的表达式”;?,typescript,Typescript,编辑:根据要求,TypeScript版本为3.2.2 关于StackOverflow上的这一特定错误,有很多问题和答案,但没有一个能令人满意地解释发生这种情况的原因 据我所知,如果我有这样的类型: type Something = number[] | string[] 然后,某物可以是数字数组,也可以是字符串数组。无论数组的内容如何,它都应该具有类似filter和map的属性。但如果我在函数中使用此类型: function doSomething(s: Something): void {
type Something = number[] | string[]
然后,某物
可以是数字数组,也可以是字符串数组。无论数组的内容如何,它都应该具有类似filter
和map
的属性。但如果我在函数中使用此类型:
function doSomething(s: Something): void {
s.map()
}
然后抛出无法调用表达式..
错误
将某物
更改为:
type Something = (number | string)[]
现在TypeScript不会抱怨呼叫签名,但我不明白为什么。出于所有目的,(number | string)[
和number[]| string[]
对我来说都是一样的。它可以是包含数字的数组,也可以是包含字符串的数组。在定义这样的类型时,调用签名似乎并不相关
这些文件甚至说:
联合类型描述的值可以是多种类型之一。我们使用垂直条(|)来分隔每种类型,因此number | string | boolean是值的类型,可以是数字、字符串或布尔值
以及:
如果一个值的类型是a | B,我们只能确定它有a和B都有的成员
因此,即使从我在官方文件中看到的情况来看,number[]| string[]
和(number | string)[]
的行为应该是相同的
这是虫子吗?我是没有抓住重点,还是过于密集?我知道这似乎与大多数人无关,但我真的试图理解这一点,所以我希望有人能提供一个像样的解释。事实上,TypeScript团队几天前发布了TypeScript 3.3。这本书也有有益的背景。TypeScript团队也有
但简单地说,当第一次设计联合类型上的调用方法时,TypeScript团队最初“出于安全考虑,很多时候错误地说签名必须相同”,以便方法可以调用 TypeScript 3.3中最近的更改在某种程度上改善了这种情况,当联合的参数共享一个公共类型时,对联合的方法调用现在可以工作,例如:
type Fruit = "apple" | "orange";
type Color = "red" | "orange";
type FruitEater = (fruit: Fruit) => number; // eats and ranks the fruit
type ColorConsumer = (color: Color) => string; // consumes and describes the colors
declare let f: FruitEater | ColorConsumer;
f("orange"); // It works! Returns a 'number | string'.
但是,即使使用此新修复程序:
只有当联合体中最多有一个类型具有多个重载,并且联合体中最多有一个类型具有泛型签名时,这种新行为才会生效。这意味着number[]| string[]
上的方法,比如map
(它是通用的)仍然不能调用
从本质上讲,对于TypeScript团队来说,合理地实现它只是一个相当复杂的问题,他们还没有完全制定出最佳的解决方案。可以公平地说,当前的行为并不是事情应该的工作方式,因此如果你愿意,可以称之为bug。似乎相关,这很有启发性,我非常感谢你分享它。在公共关系中,他提到“有了更多的基础设施,这可能是可以修复的”,我想知道你是否知道他的意思?不管怎样,这回答了我的问题,还有一些,我想我现在会忽略这种行为。我想他是说,TypeScript代码库中处理这种性质类型的现有代码还没有开发到可以轻松处理问题的程度。但我不知道具体缺少什么。