GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||
GeezerVison is showing github.com — Destructuring by ahejlsberg · Pull Request #1346 · microsoft/TypeScript Conversation
Member
This pull request adds support for ECMAScript 6 destructuring declarations and assignments with down-level ES3 and ES5 code generation. For example: var [x, y] = [10, 20]; [x, y] = [y, x]; The above example generates: var _a = [10, 20], x = _a[0], y = _a[1]; _b = [y, x], x = _b[0], y = _b[1]; Another example: interface NameAndLocation { name: string; location: [number, number]; } function getNameAndLocation(): NameAndLocation { return { name: "top-left", location: [10, 20] }; } function displayNameAndLocation({name, location: [x, y] = [0, 0]}: NameAndLocation) { console.log("name=" + name + " x=" + x + " y=" + y); } var {name, location: [x, y]} = getNameAndLocation(); displayNameAndLocation(getNameAndLocation()); The above example generates: function getNameAndLocation() { return { name: "top-left", location: [10, 20] }; } function displayNameAndLocation(_a) { var name = _a.name, _b = _a.location, _c = _b === void 0 ? [0, 0] : _b, x = _c[0], y = _c[1]; console.log("name=" + name + " x=" + x + " y=" + y); } var _a = getNameAndLocation(), name = _a.name, _b = _a.location, x = _b[0], y = _b[1]; displayNameAndLocation(getNameAndLocation()); Work still remaining:
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactionsConflicts: src/compiler/binder.ts src/compiler/checker.ts src/compiler/diagnosticInformationMap.generated.ts src/compiler/diagnosticMessages.json Require RHS of array destructuring to be an actual array type (i.e. assignable to any[]) Tighten test for tuple type (previously just required a "0" property) Support .d.ts generation for functions with destructuring parameters
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is repeated below in the emitter. Extract out a helper 'isDestructuringAssignment' function.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactionsConflicts: src/compiler/checker.ts src/compiler/diagnosticInformationMap.generated.ts src/compiler/diagnosticMessages.json src/compiler/emitter.ts src/compiler/parser.ts src/compiler/types.ts src/services/navigationBar.ts tests/baselines/reference/assignmentLHSIsValue.errors.txt tests/baselines/reference/objectTypesWithOptionalProperties.errors.txt tests/baselines/reference/parserErrorRecovery_ParameterList2.errors.txt
Contributor
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Contributor
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Member
Author
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Irony, i know: But this seems much more verbose than before. however, that's not my major issue with this change. My primary concern is that by writing the code in this manner, it puts the onus on the maintainer to be sure that the saved state is restored properly. The prior form ensured that the state would always get saved/restored properly, and no changes could accidently affect that. If you are concerned that you need to call parseIdentifierOrPattern with a parameter, and you don't want a lambda allocation, then this is a suitable way to write things: node.name = inGeneratorParameterContext() ? doInYieldContext(parseParameterIdentifierOrPattern) : parseParameterIdentifierOrPattern(); ... function parseParameterIdentifierOrPattern() { return parseIdentifierOrPattern(SyntaxKind.Parameter); }
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Contributor
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Member
Author
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Contributor
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. New SyntaxKind.BindingElement Introduced new VariableLikeDeclaration and BindingElement types Cleaned up VariableDeclaration, ParameterDeclaration, PropertyDeclaration types Node kind of binding element is always SyntaxKind.BindingElement Changed CheckVariableDeclaration to CheckVariableLikeDeclaration Reorganized CheckVariableLikeDeclaration Move downlevel vs. ES6 emit branching into individual emit functions
Anders Hejlsberg (ahejlsberg)
force-pushed
the
destructuring
branch
from
657f844 to
459dee0
Compare
Contributor
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
|
|
👍 |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Conflicts: src/compiler/binder.ts src/compiler/checker.ts src/compiler/emitter.ts src/compiler/parser.ts src/services/services.ts tests/baselines/reference/parserCommaInTypeMemberList2.errors.txt
Destructuring
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't the type be any if the parent type was any?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
It is if there is not an initializer. If you're suggesting it should be any regardless of the initializer, then no. Consider:
var a: any; var [x, y = 1] = a;
Here, a provides no clue as to the intended type of x and y, so we infer from the type of the initializer. This contrasts with:
var a: any; var [x, y = 1] = [a, a];
Here, the type of a is the intended type for y, and the initializer is required to be assignment compatible with that type.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Do we do that for contextual typing? An analogous example (courtesy of Cyrus Najmabadi (@CyrusNajmabadi)):
var v: (a: any) => void = (a = 1) { a.blah };
Should a in the body be of type any or number? Applying the reasoning you stated from destructuring, it seems like in this example it should be number, not any.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
For a parameter the order of precedence is this:
For a binding element it is this:
So, you can't really apply the reasoning of one to the other. They're different kinds of constructs.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I understand that the way you described is how things are working, but it doesn't seem self explanatory why that is the case. Why are they different constructs?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I assume you agree with the already existing rules for parameters, so I won't try to elaborate on those.
For a destructuring element, the high order bit is the type of the value being deconstructed. Indeed, the initializer isn't even evaluated when a deconstructed value is available. So, this establishes the intuition that the binding element type should primarily come from the corresponding property or element in the deconstructed type. Then, in cases where the type of the deconstructed value isn't known or is any, it makes sense to take a clue from the initializer. That's the next best source of information.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
That makes a lot of sense, but why is that not the case for parameters? I don't necessarily agree with the rules for parameters. I buy your argument about the destructuring and would like to apply it to parameters
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.