Skip to content

When the initial element of the tuple is a rest element, it is not possible to correctly infer the type of the initial element. #56883

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

Closed
13OnTheCode opened this issue Dec 26, 2023 · 6 comments

Comments

@13OnTheCode
Copy link

πŸ”Ž Search Terms

initial element of the tuple is a rest element

πŸ•— Version & Regression Information

⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.3.2#code/C4TwDgpgBAKgjFAvFA2gOgwZ2AJwJYB2A5igLoA0UBArgLYBGEOl9A9qwDYQCGBpAsACghAEwgBjDtxzRxrAtijScALlhwhQuQuBQAFjxFIlOHCgAMAwVBsB6W1AB6AfiE2o9qAFEAHpHHAECJq2PjEUAA+VHSMOEA

πŸ’» Code

type T1 = [...string[], number, boolean]

declare const arr: T1

const head = arr[0]
   // Actual: string | number | boolean
   // Expected: string | number

πŸ™ Actual behavior

When the initial element of the tuple is a rest element, it is not possible to correctly infer the type of the initial element.

πŸ™‚ Expected behavior

Infer the correct type.

Additional information about the issue

No response

@jcalz
Copy link
Contributor

jcalz commented Dec 27, 2023

This is behaving as designed according to #41544 and therefore not considered a bug:

indexing a tuple type beyond its starting fixed elements (if any) yields a union type of all possible element types

Perhaps you'd like to rephrase this as a feature request?

@julienandreu
Copy link

From my understanding, your initial type string[] could be an empty array, so Typescript won't be able to determine exactly the type of your first item.

Here is a quick example:
https://www.typescriptlang.org/play?ts=5.3.2#code/C4TwDgpgBAKgjFAvFA2gOgwZ2AJwJYB2A5igLoA0UBArgLYBGEOl9A9qwDYQCGBpAsACghAY1YFsUbjhwAuWAmQo4lXNQikA3ENHjJACx4ATJFJkoADAMFRbAejtQAegH4htqA6gBRAB6QRYAgjeWx8YigAHyo6RhwgA

Let me know if I missed something

@jcalz
Copy link
Contributor

jcalz commented Dec 27, 2023

You missed that it couldn't be boolean; you can imagine expanding [...string[], number, boolean] to [number, boolean] | [string, number, boolean] | [string, ...string[], number, boolean] and thus the element at 0 is either number or string. So OP expects string | number, but the feature was implemented to give the union of all element types, string | number | boolean. This is not a bug but it could be considered a missing feature.

@jcalz

This comment was marked as outdated.

@craigphicks
Copy link

craigphicks commented Dec 28, 2023

@jcalz

This is behaving as designed according to #41544 and therefore not considered a bug:

That's out of date with whatever changes were made in 5.0.8 that fixed #49138.
For that reason I would say this is a bug and suggest is be reopened (*but not for the same reason I said before).

See the following examples:

type T1 = [...string[], number, boolean]

const arr1: T1 = [2, true];
const arr2: T1 = ["", 2, true];
const arr3: T1 = [true];

declare const arr: T1;
const head = arr[0]
   // Actual: string | number | boolean
   // Expected: string | number

@jcalz
Copy link
Contributor

jcalz commented Dec 28, 2023

I continue to be confused by these comments (especially when they get deleted out of the middle of a discussion). It is by design that T1[0] is string | number | boolean. Yes, that type is wider than it should be, but that's not a bug, it's a design decision. There might well be bugs having to do with leading/middle rest elements in tuple types, but this is not one of them. Maybe I'm wrong, though? If so you'd do better to file a new bug about this rather than asking OP to reopen this one. But my expectation is that it would not be considered a bug. I think I'm probably done with this discussion here, so I hope you'll forgive me if I don't respond to further comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants