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

Transform TypeScript "declare" fields #10546

Conversation

nicolo-ribaudo
Copy link
Member

@nicolo-ribaudo nicolo-ribaudo commented Oct 13, 2019

Q                       A
Fixed Issues?
Patch: Bug Fix?
Major: Breaking Change?
Minor: New Feature? Yes
Tests Added + Pass? Yes
Documentation PR Link
Any Dependency Changes?
License MIT

Since there is a breaking change (uninitialized fields are now initialized to undefined), I enabled it behind an option (allowDeclareFields). This option is similar to useDefineForClassFields (microsoft/TypeScript#27644), except that [[Set]] vs [[Define]] is set by the loose option of the properties transform plugin.

Incidentally, this PR fixes #10311 when the plugins are used in the correct order.

Comment on lines +84 to +132
method({ node }) {
if (node.accessibility) node.accessibility = null;
if (node.abstract) node.abstract = null;
if (node.optional) node.optional = null;

// Rest handled by Function visitor
},
constructor(path, classPath) {
// Collects parameter properties so that we can add an assignment
// for each of them in the constructor body
//
// We use a WeakSet to ensure an assignment for a parameter
// property is only added once. This is necessary for cases like
// using `transform-classes`, which causes this visitor to run
// twice.
const parameterProperties = [];
for (const param of path.node.params) {
if (
param.type === "TSParameterProperty" &&
!PARSED_PARAMS.has(param.parameter)
) {
PARSED_PARAMS.add(param.parameter);
parameterProperties.push(param.parameter);
}
}

if (parameterProperties.length) {
const assigns = parameterProperties.map(p => {
let id;
if (t.isIdentifier(p)) {
id = p;
} else if (t.isAssignmentPattern(p) && t.isIdentifier(p.left)) {
id = p.left;
} else {
throw path.buildCodeFrameError(
"Parameter properties can not be destructuring patterns.",
);
}

return template.statement.ast`this.${id} = ${id}`;
});

injectInitialization(classPath, path, assigns);
}
},
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code for method and constructor has just been moved here from the lines before, so that all the class members "visitors" are together.

api.assertVersion(7);

const JSX_ANNOTATION_REGEX = /\*?\s*@jsx\s+([^\s]+)/;

const classMemberVisitors = {
field(path) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't use the ClassProperty visitor because the class fields transform transforms them using the Class visitor, so they would never be visited in practice.

@nicolo-ribaudo
Copy link
Member Author

cc @babel/typescript

@nicolo-ribaudo nicolo-ribaudo added the PR: Needs Review A pull request awaiting more approvals label Oct 17, 2019
`TypeScript 'declare' fields must first be transformed by ` +
`@babel/plugin-transform-typescript.\n` +
`If you have already enabled that plugin (or '@babel/preset-typescript'), make sure ` +
`that it runs before any plugin related to additional class features:\n` +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: s/ / /g
(Even though I could comment on multiple lines, I couldn't submit a multiple line suggestion, else I would have created one.)

(api, { jsxPragma = "React", allowNamespaces = false }) => {
(
api,
{ jsxPragma = "React", allowNamespaces = false, declareFields = false },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we name this allowDeclareFields (or allowDeclare) to match allowNamespaces?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 allowDeclareFields

@nicolo-ribaudo nicolo-ribaudo merged commit a0f0efd into babel:feat-7.7/ts-declare-fields Nov 5, 2019
@nicolo-ribaudo nicolo-ribaudo deleted the ts-transform-declare-field branch November 5, 2019 00:53
@nicolo-ribaudo
Copy link
Member Author

Merged to #10545 (not in master yet)

nicolo-ribaudo added a commit that referenced this pull request Nov 5, 2019
* Transform TypeScript "declare" fields

* Remove multiple spaces

* declareFields -> allowDeclareFields
nicolo-ribaudo added a commit that referenced this pull request Nov 5, 2019
* Transform TypeScript "declare" fields

* Remove multiple spaces

* declareFields -> allowDeclareFields
nicolo-ribaudo added a commit that referenced this pull request Nov 5, 2019
* [parser] Add support for TS declare modifier on fields (#10484)

* [parser] Add support for TS declare modifier on fields

* Use Object.create(null)

* Comment

* Add support for TS declare types to types and generator (#10544)

* Transform TypeScript "declare" fields (#10546)

* Transform TypeScript "declare" fields

* Remove multiple spaces

* declareFields -> allowDeclareFields

* Update after rebase
@lock lock bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Feb 4, 2020
@lock lock bot locked as resolved and limited conversation to collaborators Feb 4, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: typescript outdated A closed issue/PR that is archived due to age. Recommended to make a new issue PR: Needs Docs PR: Needs Review A pull request awaiting more approvals PR: New Feature 🚀 A type of pull request used for our changelog categories
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants