Skip to content

Combining destructuring with parameter properties #5326

Open

Description

Today, we can take advantage of parameter properties to reduce the boilerplate, e.g:

class Person {
  constructor(public firstName: string, public lastName: number, public age: number) {

  }
}

Since 1.5, we can also use destructuring, e.g:

class Person {
  firstName: string;
  lastName: string;
  age: number;

  constructor({ firstName, lastName, age } : { firstName: string, lastName: string, age: number }) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
  }
}

I've tried in many ways to combine both features, but had no success. So:

  1. Is it possible to combine them nowadays, and if yes, how?
  2. If not, could it be an improvement to a future TypeScript version? E.g:
class Person {
  constructor(public { firstName, lastName, age } : { firstName: string, lastName: string, age: number }) {

  }
}

// the code above would possibly transpile to:
var Person = (function () {
    function Person(_a) {
        var firstName = _a.firstName, lastName = _a.lastName, age = _a.age;
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }
    return Person;
})();

Activity

  1. xLama commented on Oct 20, 2015

    @xLama

    I like this.

  2. DanielRosenwasser commented on Oct 20, 2015

    @DanielRosenwasser
    Member

    Vitor Buzinaro (@buzinas) I originally had this working in #1671, but didn't take it in (check out #1541). I think the issue was that it was relatively dense in semantics. I don't necessarily agree, but maybe someone else on the team can weigh in.

  3. danquirk commented on Oct 20, 2015

    @danquirk
    Member

    Note that in those proposals the parameter property modifier applied to the entire binding pattern (simpler) as opposed to the original suggestion here which in theory supports different visibility modifiers per destructured element (not sure that level of specificity would be worth it).

  4. buzinas commented on Oct 20, 2015

    @buzinas
    Author

    Dan Quirk (@danquirk) For me, if it's easier for you to do the other way, I don't really care. In fact, that was my first try (e.g public {firstName, lastName, age}), and as soon as it didn't work, I tried to use on each property, and it didn't work too.

    It would be great if we could support both (since not always we want to create properties for all the parameters, and when we want, it would be simpler to use public/private only once), but if it's easier to support only one approach, it will be great already.

    Probably it's something that people will use more and more, since destructuring is awesome.

  5. robianmcd commented on Nov 26, 2015

    @robianmcd

    just ran into this. I think either approach would satisfy most use cases. Hope to see this in a future version.

  6. laurelnaiad commented on Dec 23, 2015

    @laurelnaiad

    The first thing I tried was:

      constructor(thisProps: { public myProperty: string, public myOtherProperty: number }) {
        // etc
      }
    

    Something like this would be a nice-to-have.

  7. jack-guy commented on Feb 26, 2016

    @jack-guy

    Definitely +1 this. The alternative tends to be... bulky.

  8. albertywu commented on Mar 23, 2016

    @albertywu

    👍

  9. hrundik commented on Apr 19, 2016

    @hrundik

    👍

  10. aliatsis commented on Apr 27, 2016

    @aliatsis

    +1

  11. lekev commented on May 13, 2016

    @lekev

    +1

  12. andriilazebnyi commented on Jun 13, 2016

    @andriilazebnyi

    +1

  13. yjaaidi commented on Aug 9, 2016

    @yjaaidi

    👍

  14. 98 remaining items

  15. awlayton commented on Apr 15, 2024

    @awlayton

    Yes that is true Michael Harrington (@kibiz0r). My solution is only helpful for very specific cases. Language support for it would be much better.

  16. kibiz0r commented on Apr 16, 2024

    @kibiz0r

    Worth noting that the this.props pattern suggested by Rodrigo de Oliveira Gonzalez (@rodrigolive) has suffered some bit rot since they posted it.

    A class like this will break if you're using the ES2022 syntax for class fields, which is the default for target ES2022 or higher, including ESNext. For this to work, you'd need to set useDefineForClassFields to false in your tsconfig.

    class Foo {
      constructor(private props: { foo: number }) {}
      private foo = this.props.foo;
    }
  17. HasanMothaffar commented on Jul 24, 2024

    @HasanMothaffar

    We still want this in 2024

  18. Akxe commented on Jul 24, 2024

    @Akxe

    Oleksandr Tarasiuk (@a-tarasyuk) Where is the discussion happening? I want to follow that thread.

  19. a-tarasyuk commented on Jul 24, 2024

    @a-tarasyuk
    Contributor

    Adam Eisenreich (@Akxe) you can find the details on why the PR aiming to resolve this issue was closed here #44912 (comment). Alternatively, you can ask Ryan Cavanaugh (@RyanCavanaugh) or Daniel Rosenwasser (@DanielRosenwasser) for more detailed explanations...

  20. Akxe commented on Jul 24, 2024

    @Akxe

    Oleksandr Tarasiuk (@a-tarasyuk) The comment above is in reaction to your [comment in #44912]. (#44912 (comment)). My question is where the mentioned discussion is happening. This thread is almost dead yet there seems to be a lot of interest for this specific feature in the community. If you think that the other leading members should add to this discussion, please welcome them here, or we could even schedule some kind of "meeting" to discuss this.

  21. sukima commented on Dec 18, 2024

    @sukima

    What are the blockers to this suggestion? How can we get Parameter Properties support with Named Arguments?

  22. k41n commented on Mar 11, 2025

    @k41n

    👍

  23. RoyTinker commented on Sep 19, 2025

    @RoyTinker

    It's strange to look for and find an open issue based on something I'm currently working on, and then see that I voted for it like 8 years ago

  24. Akxe commented on Sep 19, 2025

    @Akxe

    What are the blockers to this suggestion? How can we get Parameter Properties support with Named Arguments?

    The biggest blocker is that this is purely a TS problem. Native JS have no problem with destructuring of this kind since they do not have the public/private/private keywords. That means that there would have to be a proposal backed by someone in the TS inner circle.


    My opinion: (Take it as you want, correct me if I am wrong...)
    Currently, the TS team does not want to add anything to the TS that will not be added to JS. They do not want to get into the same troubles as they got into with decorators, or import mismatched behaviours. They also do not want to make new keywords to prevent possible collisions with new future JS keywords.


    Here is an overview of what was proposed (chronologically):

    Author Tiny example My comment Link
    RyanCavanaugh constructor(public {name1, name2}) Very important persona #5326 (comment)
    ianldgs constructor({ public readonly fun: boolean }) 25+ likes; public/private per property #5326 (comment)
    casamia918 public a = props.b; constructor(props1: Props) You need to see the comment to understand #5326 (comment)
    Antoniossss private name?: string; constructor({this.name}) Dart syntax in TS #5326 (comment)
    Akxe (me) deconstructing constructor(private name: string;) "deconstructing" keyword + new syntax #5326 (comment)

    If I forgot anyone, I am sorry; it is over 100 messages with very similar-looking responses a lot of the time.

  25. ianldgs commented on Sep 19, 2025

    @ianldgs

    Adam Eisenreich (@Akxe) worth noting that my initial proposal linked has a conflict with existing JS syntax, as pointed out in this comment:
    #5326 (comment)

    My revised proposal:
    #5326 (comment)

    This one is also interesting:
    #5326 (comment)

    Edit: my current workaround:
    #5326 (comment)

  26. RyanCavanaugh commented on Sep 19, 2025

    @RyanCavanaugh
    Member

    Currently, the TS team does not want to add anything to the TS that will not be added to JS. They do not want to get into the same troubles as they got into with decorators, or import mismatched behaviours. They also do not want to make new keywords to prevent possible collisions with new future JS keywords.

    This is basically correct. The odds we'd add destructuring to parameter properties is very, very low at this point. A proposal for something like this really needs to be taken to the TC39 committee in some form or another (not sure how since visibility is not a JS concept, but since parameter properties don't work with # anyway, you could imagine just forgetting about protected).

  27. Akxe commented on Sep 19, 2025

    @Akxe

    If public/protected/private properties have not been implemented, would you be in favour of implementing them at all nowadays? If so, I feel like the reason not to extend their functionality is counterintuitive.

    Anyhow, given the fact that TC39 will never see private/protected/public, it is an opportunity to add something to the language that will never have the problem of conflicting with TC39's future intentions with JS.

  28. RyanCavanaugh commented on Sep 22, 2025

    @RyanCavanaugh
    Member

    If public/protected/private properties have not been implemented, would you be in favour of implementing them at all nowadays?

    The visibility modifiers on property declarations, yes.

    Parameter properties, absolutely not.

    I feel like the reason not to extend their functionality is counterintuitive.

    The relevant idiom here is "if you're in a hole, the first step is to stop digging"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Effort: ModerateRequires experience with the TypeScript codebase, but feasible. Harder than "Effort: Casual".In DiscussionNot yet reached consensusSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions