Skip to content
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

Unbounded arrays cannot be used as rest elements in a tuple type except at the end #42757

Open
bogdanb opened this issue Feb 11, 2021 · 4 comments
Labels
Docs The issue relates to how you learn TypeScript

Comments

@bogdanb
Copy link

bogdanb commented Feb 11, 2021

Bug Report

🔎 Search Terms

A rest element must be last in a tuple type.

🕗 Version & Regression Information

This is the behavior in every version I tried, and I reviewed the FAQ for entries about rest elements and tuples.

Specifically, I tried it with 4.1.5 right now. Note that 4.0.5 behaved a bit differently (but still buggy), see below.

Note that the behavior is normal in versions ≤4.0, since that’s when non-final rest elements were allowed in tuples.

⏯ Playground Link

Playground link with relevant code

💻 Code

type Strings = [string, string];
type Numbers = number[];

type Unbounded = [...Strings, ...Numbers, boolean]; 

🙁 Actual behavior

The ...Numbers part generates an error: TS1256: A rest element must be last in a tuple type.

This exact code appears in TypeScript 4.0 release notes, thus presumably should work. (Search for “the resulting type becomes unbounded”.)

Note: I encountered something similar with 4.0.5 earlier. There, the non-final unbounded rest elements worked, but only via a type alias. They didn’t work with literal arrays in the tuple definition:

type Numbers = number[];

type Unbounded1 = [boolean, ...number[]]; // OK
type Unbounded2 = [...Numbers, boolean]; // OK
type Unbounded3 = [...number[], boolean]; // NOK

Playground Link for TS 4.0.5

🙂 Expected behavior

The feature should work as documented. TypeScript should generate unbounded tuples type that work the “obvious” way.

@bogdanb
Copy link
Author

bogdanb commented Feb 11, 2021

It just occurred to me to test this with 4.2.0-dev in the playground. There it seems to work correctly in all cases! I suppose you could close this, unless you want to make sure it doesn’t get broken again before 4.2.0 is released.

Edit: This looks like a duplicate of #41701, but that one was closed as “working as intended” without much explanation.

Edit 2: However, #41544 seems to suggest that multiple rest elements will no longer be allowed, so my first example would no longer work? But the current beta seems to allow it. I’m not sure I get what is (and should be) allowed and what not anymore.

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Feb 11, 2021
@RyanCavanaugh
Copy link
Member

#41544 covers what's possible. You can have multiple rest elements, but only one of them can be unbounded and preserve tuple-like behavior. If you have multiple unbounded rest elements in array notation in a tuple then we'll eagerly warn you that this isn't doing what you meant, but deferred instantiations (whether through type aliases or e.g. generic instantiation) of multiple unbounded rest elements are treated as a merged array type instead, consistent with prior behavior.

@bogdanb
Copy link
Author

bogdanb commented Feb 11, 2021

Alright, thank you, that's a clear summary. Is this documented somewhere I didn't notice? I did read #41544, but I still wasn't sure by the end what was and wasn't meant to work.

The original example above came from the TypeScript handbook, which does not suggest the behavior you describe. Should it maybe be amended? Or at least a note added that this changed between minor versions, with a link to the new behavior?

@RyanCavanaugh RyanCavanaugh added Docs The issue relates to how you learn TypeScript and removed Duplicate An existing issue was already created labels Feb 12, 2021
@RyanCavanaugh
Copy link
Member

Good call, we should update the docs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Docs The issue relates to how you learn TypeScript
Projects
None yet
Development

No branches or pull requests

2 participants