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

Labeled variadic tuples should not require labeling spreads for tuples that are already labeled #52853

Closed
5 tasks done
btoo opened this issue Feb 19, 2023 · 3 comments Β· Fixed by #53356
Closed
5 tasks done
Labels
Experience Enhancement Noncontroversial enhancements Help Wanted You can do this Suggestion An idea for TypeScript
Milestone

Comments

@btoo
Copy link

btoo commented Feb 19, 2023

Suggestion

πŸ” Search Terms

variadic tuples name label element named labeled tuple elements

βœ… Viability 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, new syntax sugar for JS, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

⭐ Suggestion

Variadic tuples will inherit the labels of the tuples they're spreading

type LabeledTuple = [first: string, second: number]

type VariadicTuplesCanInheritLabels = [...LabeledTuple]
//  ^? type VariadicTuplesCanInheritLabels = [first: string, second: number]

However, once a variadic tuple adds unlabeled elements, the variadic tuple loses the spread tuples' labels and compilation fails

type VariadicTuplesWithoutLabelingALabeledTuple = [...LabeledTuple, third: boolean]
//  ERROR: Tuple members must all have names or all not have names. (5084)

As a workaround, we can label the spread, but this label never gets used. Even worse (and potentially a bug), this label's type is inferred as any

/** `unusedLabel`'s type is incorrectly inferred as `any` */
type VariadicTupleWithUnusedLabel = [...unusedLabel: LabeledTuple, third: boolean]
//  ^? type VariadicTupleWithUnusedLabel = [first: string, second: number, third: boolean]

Following up on #39941 (comment), a better DX might be to not require that Tuple members must all have names if the spread elements are already labeled, which would be consistent with the fact that variadic tuples already inherit the labels of their spreads.

πŸ“ƒ Motivating Example

Playground link

πŸ’» Use Cases

Not having to redundantly label variadic tuple spreads

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript In Discussion Not yet reached consensus labels Feb 22, 2023
@btoo btoo changed the title Variadic tuples should not require labeling spreads that are already labeled Labeled variadic tuples should not require labeling spreads that are already labeled Feb 23, 2023
@btoo btoo changed the title Labeled variadic tuples should not require labeling spreads that are already labeled Labeled variadic tuples should not require labeling spreads for tuples that are already labeled Feb 23, 2023
@RyanCavanaugh RyanCavanaugh added Help Wanted You can do this Experience Enhancement Noncontroversial enhancements and removed In Discussion Not yet reached consensus labels Feb 28, 2023
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Feb 28, 2023
@RyanCavanaugh
Copy link
Member

Discussed and we're OK removing this restriction for all tuple elements. However, #53011 would need to be fixed first, otherwise we might break currently-working declaration emit

@JoshuaKGoldberg
Copy link
Contributor

removing this restriction for all tuple elements

@RyanCavanaugh just to be clear, are you suggesting that the Tuple members must all have names or all not have names restriction is clear to be removed altogether?

@RyanCavanaugh
Copy link
Member

Yeah, though we should make the declaration emitter more resilient to this. Sample:

function fn() {
    type M = [a: string, number];

    return f;

    function f(...args: M) { }
}

I think we want the function type in the .d.ts to be something like (a: string, arg_1: number) => void

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Experience Enhancement Noncontroversial enhancements Help Wanted You can do this Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants