Skip to content

Transform TypeScript "declare" fields#10546

Merged
nicolo-ribaudo merged 3 commits intobabel:feat-7.7/ts-declare-fieldsfrom
nicolo-ribaudo:ts-transform-declare-field
Nov 5, 2019
Merged

Transform TypeScript "declare" fields#10546
nicolo-ribaudo merged 3 commits intobabel:feat-7.7/ts-declare-fieldsfrom
nicolo-ribaudo:ts-transform-declare-field

Conversation

@nicolo-ribaudo
Copy link
Copy Markdown
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 babel/website#2196
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.

@nicolo-ribaudo nicolo-ribaudo added PR: New Feature 🚀 A type of pull request used for our changelog categories area: typescript labels Oct 13, 2019
@nicolo-ribaudo nicolo-ribaudo added this to the TypeScript 3.7 milestone Oct 13, 2019
@nicolo-ribaudo nicolo-ribaudo force-pushed the feat-7.7/ts-declare-fields branch from 9cf1244 to 6faf79a Compare October 13, 2019 23:00
@nicolo-ribaudo nicolo-ribaudo force-pushed the ts-transform-declare-field branch from 41eefc2 to b2a6971 Compare October 13, 2019 23:01
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
Copy Markdown
Member Author

@nicolo-ribaudo nicolo-ribaudo Oct 15, 2019

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.

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

const classMemberVisitors = {
field(path) {
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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 force-pushed the ts-transform-declare-field branch from 127754a to c188fc4 Compare October 22, 2019 22:26
@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
Copy Markdown
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 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.

3 participants