microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
101.21k stars 12.51k forks source link

Tuple Spread Inconsistencies When Intersected #60539

Open LukeAbby opened 5 days ago

LukeAbby commented 5 days ago

🔎 Search Terms

Tuple, Intersection, Spread

🕗 Version & Regression Information

⏯ Playground Link

https://www.typescriptlang.org/play/?#code/C4TwDgpgBAKgrmANtAvFA2gZ2AJwJYB2A5gDRQB0lBcAtgEYQ7oC6zA3AFCiSwLICSBYI0wQAxsDwB7AlDTwk0AGRQA3lDA4pYAFxRs+YlAC+nDl3DQFyAEoRsAQTFj7mOb0XoAjOw4B6PygggD0oanpGc24rPghBYRxRCWkCO0dnV3drOKERcUkZb18AoKhQg0IiKAAfMNoGHHMLHmyAZU0IAEMAE3d0SnJs4sDSsowK4jIB8IaWZijLDwFcxPyU9pwu3rR+ymz4vOSZYdLQgAoJqtqZxgBKFiA

💻 Code

type Tuple = [string, ...number[]];
type TupleIntersection = Tuple & { prop: string };

type TupleRestAccess = Tuple[1];
//   ^ number

type TupleIntersectionRestAccess = TupleIntersection[1];
//   ^ string | number

type TupleSpread = [...Tuple];
//     ^ [string, ...number[]]

type TupleIntersectionSpread = [...TupleIntersection];
//   ^ (string | number)[]

🙁 Actual behavior

TupleIntersection[1] and [...TupleIntersection] both seem to use an overly broad type, matching the number index signature instead of the more narrow spread signature.

What I mean is that TupleIntersection[1] behaves just like Tuple[number] does. This leads me to believe that the number index signature is synthesized correctly but the logic for numeric literals in the range of the spread signature aren't handled.

🙂 Expected behavior

I expected Tuple's behaviour to match TupleIntersection.

Additional information about the issue

No response

jcalz commented 5 days ago

related to #59849, #59521, #45371, #42557, #40945