Microsoft/TypeScript

Shorter tuple inference gets picked over longer inference when both come from rests

Open

#57,981 建立於 2024年3月28日

在 GitHub 查看
 (1 留言) (0 反應) (0 負責人)TypeScript (6,726 fork)batch import
Domain: check: Type InferenceHelp WantedPossible Improvement

倉庫指標

Star
 (48,455 star)
PR 合併指標
 (平均合併 6天 17小時) (30 天內合併 9 個 PR)

描述

🔎 Search Terms

inference contravariant covariance rest shorter longer tuples

🕗 Version & Regression Information

  • This is the behavior in every version I tried

⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.5.0-dev.20240327#code/CYUwxgNghgTiAEAzArgOzAFwJYHtVNQB4BBeEADwxFWAGd44pg8IBPeNAa1RwHdUA2gF0AfAAoAsACh48WAHMAXPDEA6dQtrLiASngBeEfABuOLMAA002etWbt0ndoDc0sHloZ4WVIhAw4YAMCMTEoZVRkAFsAI389Q3gAbwBfC3gARnSAJh1neAB6AvgAUXIAB3AqIOy5GHlo6gxadJjkL3kcLwBmVTFsgFYBgBYdaSLZWQA9AH54d1RPb19-QOUBcPhI2P8hNw8vHz8AkGBa-RCwiOi4mFaZ652YBKNU9Iy8wuKcTnHiydm8wOy2OgWy622tz2UgWSyOq1O3WCiFQoU2kP890etxeyTSmTk9FhGE+Ex+f0m8EBxJBCOA3XWGWhQA

💻 Code

declare function fn<A extends readonly unknown[]>(
  arg: (...args: A) => void,
  ...args: A
): A;
const inferred = fn((a: number) => {}, 1, 2); // Expected 2 arguments, but got 3.(2554)
//    ^? const inferred: [a: number]
const inferred2 = fn((a: number, b?: number) => {}, 1); // ok
//    ^? const inferred2: [number]
const inferred3 = fn((a: number, b?: number) => {}, 1 as const); // ok
//    ^? const inferred3: [1]

🙁 Actual behavior

inferred is [a: number] and the function call fails

🙂 Expected behavior

inferred should be [number, number] and the function call should succeed.

Additional information about the issue

Based on inferred2 and inferred3 we can see that the covariant inference is preferred in a situation like this. The problem is the .length mismatch between those 2 candidates but since the contravariant candidate comes from a rest position it should be ignored when comparing those 2 candidates and the covariant inference should be preferred

貢獻者指南