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

Contextually allow spread to create tuples from tuples #33783

Closed
5 tasks done
markusjohnsson opened this issue Oct 3, 2019 · 3 comments
Closed
5 tasks done

Contextually allow spread to create tuples from tuples #33783

markusjohnsson opened this issue Oct 3, 2019 · 3 comments
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@markusjohnsson
Copy link
Contributor

markusjohnsson commented Oct 3, 2019

Search Terms

tuple spread

Suggestion

Right now, I cannot create a 3-tuple from a 2-tuple using spread, like so:

type A = [number, number];
type B = [number, number, string];

const a: A = [1, 2];
const b: B = [...a, "asd"];

// Type '(string | number)[]' is missing the following properties from type '[number, number, string]': 0, 1, 2

But to me it seams that, given the expected type, TypeScript would be able to see that spreading a [number,number] and adding a string would create a [number, number, string].

Use Cases

Right now to produce a correct type B, given a value of type A, I would need to destructure and recreate the type:

const [x, y] = a;
const b: B = [x, y, "asd"];

Which works for simple tuples like this, but does not scale well.

Examples

I was working on a piece of code that looked like this:

type Result = [A, B];
function majorOperation(args) : Result  {
   const a = stuff();
   return minorOperation(a);
}

I then needed to expand the result of majorOperation to include another result, not produced by minorOperation(), so I split the result type in two and expected typescript to allow me to combine them using spread:

type MinorResult = [A, B];
type MajorResult = [A, B, C];
function majorOperation() : MajorResult  {
   const a = stuff();
   const c = produceC();
   return [... minorOperation(a), c];
}

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.
@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Oct 17, 2019
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 3.8.0 milestone Oct 17, 2019
@RyanCavanaugh
Copy link
Member

@ahejlsberg was this an oversight? It seems correct to create a tuple in the presence of a tuple contextual type

@ahejlsberg
Copy link
Member

@RyanCavanaugh No, not an oversight. Currently, anything past the first spread expression is unioned into a rest element in the resulting tuple type; and if the spread is in the first position, the result is an array type (because [...X] is the same as X[]). See also #26350.

@ahejlsberg ahejlsberg added Suggestion An idea for TypeScript and removed Needs Investigation This issue needs a team member to investigate its status. labels Oct 17, 2019
@RyanCavanaugh RyanCavanaugh added the Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature label Oct 17, 2019
@RyanCavanaugh RyanCavanaugh removed this from the TypeScript 3.8.0 milestone Oct 17, 2019
@markusjohnsson
Copy link
Contributor Author

Works as of TS 4.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

3 participants