重载不是类型检查主体
Posted
技术标签:
【中文标题】重载不是类型检查主体【英文标题】:Overloads not typechecking body 【发布时间】:2019-02-07 11:51:00 【问题描述】:TypeScript 根本不检查函数体是否与函数重载有关吗? 以下编译,虽然它显然没有按照它声称的那样做:
function a(input: string): string
function a(input: number): number
function a(input: string | number): string | number
if (typeof input === "string") return 42
return "banana"
我的第三个签名有错吗?包罗万象的签名没有出现在结果类型中,而且我不知道没有它的声明函数的方法,任何尝试都会遇到Overload signature is not compatible with function implementation.
错误。
typeof a =
(input: string): string;
(input: number): number;
我会接受切换到更明确的相交类型:
type C = ((input: number) => number) & ((input: string) => string)
但我不明白如何在不使用重载语法的情况下实际创建一个满足它的函数,这似乎是强制转换。我在Overloaded function type in typescript question 中问过这个问题。
编辑:第一块是一个极简主义的人为例子。您可以使用以下方法对其进行测试:
const number: number = a(0)
console.log("number", typeof number, number)
输出number string banana
const string: string = a("")
console.log("string", typeof string, string)
输出string number 42
编辑 2: 这不是 Overloaded function type in typescript 的副本,我问的是针对所有重载对函数实现进行类型检查,这个问题是关于用新函数实现重载类型。
【问题讨论】:
我不明白为什么你有一个声明function a(input: string): string
却从来没有发生过。与function a(input: number): number
相同
@PatrickRoberts 这是应该捕获的错误的人为示例。
啊,那我误会了。它编译的原因是因为你的最后一个声明function a(input: string | number): string | number
。如果 any 声明匹配输入和返回值之间的关系,则调用将编译。
(1) 我无法删除该声明。 (2) typeof a
中实际上并不存在该签名,只有不同的两个存在。 (3) 从编辑中可以看出,它对使用它的代码撒谎!
(1) 是的,你可以,在第二次超载后开始身体。 (2) 你的 typeof a = ...
没有编译,所以这无关紧要。您不能分配给表达式typeof a
。 (3) 你实际上还没有产生minimal reproducible example。再试一次。
【参考方案1】:
TypeScript 根本不检查函数体是否有函数重载吗?
不,它不会根据重载声明检查主体。
如您所见,它检查实现签名是否与所有重载声明兼容;它检查主体是否符合实现签名;就这样。此外,在调用站点进行重载解析时不会考虑实现签名。
强制实现与重载声明的一致性不是设计目标,至少我是这样解释 FAQ 中的这条语句的:
这里的基本原理是因为 javascript 没有函数 重载,您将在函数中进行参数检查, 这你的功能实现可能更宽容 您希望您的用户通过什么方式给您打电话。
【讨论】:
我能理解的不那么宽容,我的问题是它允许断言彻头彻尾的谎言,这是你通常只能从(x as any) as Y
演员阵容中获得的。任何地方都没有很好地记录这是多么危险。可以很容易地看到重构正文并引入了问题中的错误。以上是关于重载不是类型检查主体的主要内容,如果未能解决你的问题,请参考以下文章