🔎 搜索词
NoInfer 签名参数列表 rest
🕗 版本与回归信息
- 这是我尝试的每个版本中的行为
⏯ Playground链接
https://www.typescriptlang.org/play/?ts=5.6.0-dev.20240817#code/CYUwxgNghgTiAEAzArgOzAFwJYHtXzCggggB4BBeEADwxFWAGd44pg8IBPeNAa1RwDuqANoBdAHwAKAFDx4sAOYAueJIB0GxQxUA5HAElUiEDHLiAlPAC84+ADccWYABpZ8DWq0qy0894Dc0mB4DBjwWEYmcMDWBEQQkpJQKqjIALYARiaWNvAA3gC+zvAAjMUATOaBAPTVcvUNjfAAegD80tKgkLAIKOjYeHHE5eSUNHSMzCCs7Fy8-EJiUm6KKuqaMAra8GQ5tg5OrnIeXju+AUEhYRHGMNHlsYTDJMKpmSbFb1kwEonJ8F9stZbIVimV4JUanV6m1pEA
💻 代码
declare function call<A extends readonly unknown[]>(
arg: (...args: NoInfer<A>) => void,
...args: A
): A;
// Argument of type '(a: number) => void' is not assignable to parameter of type '(...args: NoInfer<[number, number]>) => void'.
// Types of parameters 'a' and 'args' are incompatible.
// Type '[number, number]' is not assignable to type '[a: number]'.
// Source has 2 element(s) but target allows only 1.(2345)
const inferred = call((a: number) => {}, 1, 2);
// ^? function call<[number, number]>(arg: (...args: NoInfer<[number, number]>) => void, args_0: number, args_1: number): [number, number]
declare function call2<A extends readonly unknown[]>(
arg: (...args: A) => void,
...args: A
): A;
const inferred2 = call2<[number, number]>((a: number) => {}, 1, 2);
// ^? const inferred2: [number, number]
🙁 实际行为
第一次调用无法进行类型检查。
🙂 预期行为
这两个调用都使用相同的参数。第一个使用 NoInfer
,因此协变推断可以优先处理。这防止了示例化的签名像第二个调用那样进行类型检查。请注意,第一个调用推断出与第二个调用显式提供的相同类型参数: [number, number]
关于此问题的其他信息
我认为可以通过将 NoInfer<[A, B]>
规范化为 [NoInfer<A>, NoInfer<B>]
来解决这个问题。这将类似于 instantiateMappedTupleType
今天所做的工作。
1条答案
按热度按时间rta7y2nd1#
也许这个会更好?
https://www.typescriptlang.org/play/?ts=5.6.0-dev.20240817#code/CYUwxgNghgTiAEAzArgOzAFwJYHtXzCgggB4BBeEADwxFWAGd44pg8IBPeNAa1RwDuqANoBdAHwAKAFDx4sAOYAueADkcASVSIQMEpIB0RxQxVkAlPAC84+ADccWYOIA0s+EYMmz082YDc0mB4DBjwWNq6cMDWBEQQkpJQKqjIALYARrqWNvAA3gC+LvAAjMUATOaBAPTVcvUNjfAAegD80tKgkLAIKOjYeHHE5eSUNHSMzCCs7Fy8-EJiUu6KKobGMAqm8BbWtg5ObnKe3ju+AUEhYRE6MNHlsYTDJMKpmbrFb1kwEonJ8F9snt8kVShUqtJag02tIgA