Microsoft/TypeScript

Signatures with less parameters aren't assignable to compatible targets with more when their rest param is an instantiated `NoInfer`

Open

#59.668 aperta il 17 ago 2024

Vedi su GitHub
 (2 commenti) (1 reazione) (0 assegnatari)TypeScript (6726 fork)batch import
Domain: check: Type InferenceHelp WantedPossible Improvement

Metriche repository

Star
 (48.455 star)
Metriche merge PR
 (Merge medio 6g 17h) (9 PR mergiate in 30 g)

Descrizione

🔎 Search Terms

NoInfer signature parameters list rest

🕗 Version & Regression Information

  • This is the behavior in every version I tried

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.6.0-dev.20240817#code/CYUwxgNghgTiAEAzArgOzAFwJYHtXzCgggB4BBeEADwxFWAGd44pg8IBPeNAa1RwDuqANoBdAHwAKAFDx4sAOYAueJIB0GxQxUA5HAElUiEDHLiAlPAC84+ADccWYABpZ8DWq0qy0894Dc0mB4DBjwWEYmcMDWBEQQkpJQKqjIALYARiaWNvAA3gC+zvAAjMUATOaBAPTVcvUNjfAAegD80tKgkLAIKOjYeHHE5eSUNHSMzCCs7Fy8-EJiUm6KKuqaMAra8GQ5tg5OrnIeXju+AUEhYRHGMNHlsYTDJMKpmSbFb1kwEonJ8F9stZbIVimV4JUanV6m1pEA

💻 Code

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]

🙁 Actual behavior

The first call fails to typecheck

🙂 Expected behavior

Both of those calls use the same arguments. The first one is using NoInfer so the covariant inference can get prioritized. That prevents the instantiated signature from typechecking like the second one. Note that the first call infers the same type argument as the one that is supplied explicitly to the second call: [number, number]

Additional information about the issue

I think that this can be fixed by normalizing NoInfer<[A, B]> to [NoInfer<A>, NoInfer<B>]. This would be similar to what instantiateMappedTupleType does today at times.

Guida contributor