-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Type tuples no longer inferred properly from rest arguments with mapped generic type tuples. #49556
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@typescript-bot bisect good v4.6.4 bad v4.7.4 |
The change between v4.6.4 and v4.7.4 occurred at 787bb9d. |
What was the purpose of this conditional type? At a glance it seems like it should always evaluate true. |
👋 Hi, I'm the Repro bot. I can help narrow down and track compiler bugs across releases! This comment reflects the current state of the repro in the issue body running against the nightly TypeScript. Issue body code block by @joelek
Historical Information
|
So, at first glance, the above appears to be intended to filter the keys of a tuple type to only the numeric indexes (so, filter out any named things like if you had type TupleMapper2<Tuple extends any[]> = {
[Key in keyof Tuple]: Key extends number ? MyMappedType<Tuple[Key]> : never;
}; This doesn't doesn't compile and has a confusing error at the call. But, depending on what we think #48837 seems to be intended to change indexed accesses to arrays/tuples to not only be type TupleMapper3<Tuple extends any[]> = {
[Key in keyof Tuple]: Key extends (number | `${number}`) ? MyMappedType<Tuple[Key]> : never;
}; And this compiles with the original example in 4.7, so maybe it's a workaround? If we go back to the original example, it would seem like we could make the same transformation by adding type TupleMapper4<Tuple extends any[]> = {
[Key in keyof Tuple]: Tuple[Key] extends (Tuple[number] | Tuple[`${number}`]) ? MyMappedType<Tuple[Key]> : never;
}; Except that we get an error that says that All examples better laid out here: Playground Link |
I think the upshot of this is that the purpose of the conditional type was to do exactly what #48837 does unconditionally, so it can just be removed. The conditional type is a workaround for the previous weird behavior of mapping over generic tuples/arrays. That said, I think the lost inference in the original example is still probably a bug. |
Just to complete my side investigation, the "Type ' |
Helpers like the conditionally mapped type I started using the pattern a few years ago due to having issues with unwanted mapping over non-numeric keys and I believe that the pattern is somewhat well-established in code bases. The fix is simple, just remove the conditional, but the weird behavior of lost inference in certain circumstances might leave people puzzled and could, as you say, indicate a bug. |
This seems to have turned out to just be a bug; see #52848. |
I recently updated the dependencies for a TypeScript-based project and unfortunately ended up with some unexpected breakage.
The TypeScript version was changed from 4.6 to 4.7 and type tuples are no longer inferred properly from rest arguments with mapped generic type tuples.
The project uses several helper types to map type tuples to other type tuples as shown below.
After updating to TypeScript 4.7 it is still possible to use the helper directly. TypeScript will correctly infer the type as expected.
However, type inference breaks when using the mapper to map the rest arguments of a generic function as shown below.
The problem can be mitigated by explicitly specifying the generic type tuple argument. It can also be solved by removing the mapping constraints in the mapper as shown below.
I decided to open this issue and let you decide if this is something worth investigating since I couldn't find any information about the difference in behaviour in the release notes.
🔎 Search Terms
tuple mapping
type inference
rest arguments
generics
🕗 Version & Regression Information
This changed between versions 4.6 and 4.7.
⏯ Playground Link
Playground 4.6.4
Playground 4.7.2
💻 Code
🙁 Actual behavior
The type tuple is inferred as [unknown, unknown] in TypeScript 4.7.
🙂 Expected behavior
The type tuple is inferred as [string, number] in TypeScript 4.7.
The text was updated successfully, but these errors were encountered: