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

Simplify object destructuring in argument #14856

Closed
antanas-arvasevicius opened this issue Mar 25, 2017 · 6 comments
Closed

Simplify object destructuring in argument #14856

antanas-arvasevicius opened this issue Mar 25, 2017 · 6 comments
Labels
Duplicate An existing issue was already created

Comments

@antanas-arvasevicius
Copy link

Hello,
when doing some prototyping and playing with object destructuring in function argument I've noticed that I must duplicate identifier names in type information and if there are many variables it looks heavier:

function mainLayoutComponent({banners, profile, cart}: { banners: Component, profile: Component, cart: Component }): any { }

Proposal:
My suggestion would be that destructuring in function argument position would allow type information definition if object type is not explicitly defined:
function mainLayoutComponent({banners: Component, profile: Component, cart: Component}): any { }

It would be handy. I don't know how that sounds from language design perspective as it feels like it will be possible to define a function which argument identifier is "unknown" but with given type information.

Compiler could translate that kind of construct into destructuring syntax before compilation.

Note: I've seen propsal with :: operator (#13471) which was rejected, but this "special treatment" of destructuring in argument space looks ES6, ES7 compatible.

@antanas-arvasevicius
Copy link
Author

Sorry, seems like : is reserved in ES6 for variable rename. What a loss.. Haven't reasoned to add some compiler flag enableES6DestructuringRename to bypass default?

#7576

@aluanhaddad
Copy link
Contributor

The flag name --enableES6DestructuringRename suggests the current behavior would be disabled by default, an inherently problematic suggestion but, regardless, I can't think of a situation where the proposed behavior should reasonably be used.
It would mean that a function could have two completely different meanings depending on the value of the flag. Either a bunch of new identifiers are injected into a function's scope or a bunch of identifiers are removed from that scope. Either represents a dramatic change to the lexical environment. I realize that it would likely result in errors but it still seems dangerous.

I understand your frustration with the current behavior. In addition to being ugly, I would say that the parameter destructuring renaming provided by : pollutes a function's interface with its implementation details for source level consumers. In addition to the typing issues I tend to avoid parameter destructuring for this reason as well.

Sadly, I don't think there's any getting around it.

@antanas-arvasevicius
Copy link
Author

antanas-arvasevicius commented Mar 25, 2017

Yes, with --enableES6DestructuringRename would be completed different universes and I know that TypeScript philosophy wouldn't let anybody to drift off the ES standards, so, that nonsensical "variable renaming" will stay till official deprecation.

Currently, I see only one solution - to not use object destructuring:
function mainLayoutComponent(args:{banners: Component, profile: Component, cart: Component}): any { }

Or introduce some "Interface Spread To Variables" operator which could be used as such:
function mainLayoutComponent(...{banners: Component, profile: Component, cart: Component}): any { }
function mainLayoutComponent(...LayoutOptions): any { }

@nfour
Copy link

nfour commented Mar 27, 2017

facebook/flow#235

The guys at flow had a bit of a discussion about this same issue.

I'm partial to this syntax:

const MyComponent = ({
  (aProp: string),
  someProp: (renamedProp: number),
  (onClick: (event: Event) => void),
}) => {}

The syntax is highlighted in VSCode correctly which is nice, and it's invalid JS to use an expression inside destructuring, which means it won't conflict with backwards compatibility.

I think it looks readable enough except for the implication you're defining a self-calling object or something as in a ts.d

Or

const MyComponent = ({
  aProp as string,
  someProp: renamedProp as number,
  onClick as (event: Event) => void,
}) => {}

@mhegazy
Copy link
Contributor

mhegazy commented Mar 27, 2017

As noted in #7576 (comment), the TC39 choice of syntax for this feature is unfortunate, and I feel your pain using it day in and day out. However, adding new non-standard syntax is not a good solution either. We would like to keep expression-level syntax as close as possible to the standard JS syntax.

@mhegazy
Copy link
Contributor

mhegazy commented Mar 27, 2017

Also I would say this is a duplicate of #7576, with just new syntax proposal.

@mhegazy mhegazy added the Duplicate An existing issue was already created label Mar 27, 2017
@mhegazy mhegazy closed this as completed Apr 19, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 21, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants