我遇到了与typescript中的函数重载有关的错误,并编写了这个最小的例子来重现错误。
interface XComplex {
value: X
}
type X = string | XComplex
interface YComplex {
value: Y
}
type Y = string | YComplex
function transform(v: string): string
function transform(v: XComplex): YComplex
function transform(x: X): Y {
if (typeof x === "string") {
return x
}
const xValue: X = x.value
return {
value: transform(xValue), // <---- **ERROR**
}
}
// **ERROR**
// [ts]
// Argument of type 'X' is not assignable to parameter of type 'XComplex'.
// Type 'string' is not assignable to type 'XComplex'.
如果我删除了重载的签名但是以下用例不起作用,则不会发生错误。
// WITH OVERLOADING
const yString1: string = transform('hello')
const yComplex1: YComplex = transform({ value: 'xValue'})
// WITHOUT OVERLOADING
const yString2: Y = transform('hello')
const yComplex2: Y = transform({ value: 'xValue'})
在错误中,似乎“类型'X'的参数”是xValue,它“不能分配给'XComplex'类型的参数”,它将是变换的参数。但是变换采用了类型X的参数,所以我不确定我做错了什么。
编辑1:
似乎如果我添加额外的重载签名,它就会按预期工作。
function transform(v: string): string
function transform(v: XComplex): YComplex
function transform(v: X): Y <--- EXTRA OVERLOADED SIGNATURE
function transform(x: X): Y { ... }
现在我只是不确定为什么这是必要的,或者如何从错误信息中理解这一点。
编辑2:
在考虑了这个之后,我想因为xValue是X类型,所以typescript不可能知道它是字符串还是XComplex而且没有
function transform(v: string): string
function transform(v: XComplex): YComplex
会匹配。我假设那个打字稿只是一个接一个地通过签名,直到它到达最后一个,并且实现没有匹配,所以它只输出“类型'X'的参数不能分配给'XComplex'类型的参数。”指最后一个签名。表示没有重载签名匹配的错误似乎更有帮助。
这就解释了为什么“赶上所有”的情况
function transform(v: X): Y <--- EXTRA OVERLOADED SIGNATURE
是必要的。