🔎 搜索词
带注解的,“rest参数”
🕗 版本与回归信息
- 我尝试的每个版本都有这种行为
⏯ Playground链接
https://www.typescriptlang.org/play/#code/GYVwdgxgLglg9mABAWwNYEFrzAHgJJgAOIUiApgB5RlgAmAzogIZgCeA2gLoB8AFE1gQAuRAG8AUIimJgARiG8AdMor0hBYlACUiALzdEANzgxaAGknTgAJgXLFq9URI79Rk+fEBfHaK-jxNExYBF4JaRlZXgoheigAJxgwAHMzRFYhMBBkACMyeN8vC0spG2i01kKLCIB6GsQKZjp05niyRCTgfLbaZkYAIhZWfurpOvJDGkQoAAs4EGSZmWsOxk7usl6mAeiROMSUipEs3PzXA2NTfu8tAG5xIA
💻 代码
function mkAction<Input extends any[]>(action: {
f1:(...xs:Input) => void,
f2:(...xs:Input) => void,
}) {}
mkAction({
f1(x:string, y:number) {},
f2(x, y) {},
// x and y are inferred as "any",
// even though f2 is inferred as "(x: string, y: number) => void"
});
🙁 实际行为
参数 "x" 和 "y" 被推断为 "any",尽管 "f2" 具有正确的类型 (x: string, y: number) => void
🙂 预期行为
我希望对 "f2" 的参数进行 x: string
和 y: number
的推断。
关于问题的附加信息
- 无响应*
2条答案
按热度按时间fdbelqdn1#
related to #47599
6bc51xsx2#
这是一个有趣的问题。
inferFromAnnotatedParameters
的确不会从剩余参数中推断,它也不会尝试将推断结果与上下文中的剩余参数统一。第一个问题体现在另一个问题上:这个问题似乎是一个相对容易解决的问题,我在这里没有看到额外的考虑因素。
第二个问题(与 OP 的问题相关)也不太难在这里实现。然而,这个问题有一些额外的考虑因素。剩余参数的问题在于我们不知道它实际上可能有多少个项目。据我所知,对于这种推断出的元组,没有统一算法。
如果能推断出
[x: string, y: number, z: string]
就好了,但它首先推断出了[x: string, y: number]
,然后推断出了第二个[x: string, y: number, z: string]
候选项。当它有两个这样的候选项时,它会选择第一个。这样一来,它就无法通过签名适用性检查,因为在示例化后,事实证明f2
应该为(x: string, y: number) => void
,但提供的参数需要多一个参数。这里还有一个额外的错误...当悬停在
mkAction3
调用上时,我们可以看到错误的签名:这个类型参数没有被推断为
any[]
- 它被推断为[x: string, y: number]
。如果我们手动提供any[]
,这个调用将会成功。另一方面...关于不同形状的元组,这是目前已经实现的功能,所以我不确定担心这个问题是否合理。
另一个有趣的事情是,在原始问题中,上下文签名有一个剩余参数。在这种情况下,使用非固定推理Map器示例化上下文签名。这与上下文签名没有剩余参数的情况不同,因为在那种情况下,使用固定推理Map器。它们之间有一个重要的区别,固定的Map器可以使用
inferFromIntraExpressionSites
,而非固定的Map器不能。此对象中的前一个方法就是这样的一个表达式内部推理站点,如果那个非固定Map器或者我们在示例化该上下文签名时切换到固定Map器使用它,那么这也会正确地推断出来。从这些内部表达式站点进行推断绝对是为了修复推理的,因此将其包含在非固定Map器中是不正确的。我不知道如果只是切换到使用固定Map器会发生什么问题,但这里的区分必须存在,代码的结构使得这绝对不是误操作。
无论如何,我可能会对
inferFromAnnotatedParameters
进行更改,然后尝试探索如何统一从剩余参数中进行的逆变推理。