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
Transform TypeScript "declare" fields #10546
Conversation
9cf1244
to
6faf79a
Compare
41eefc2
to
b2a6971
Compare
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); | ||
} | ||
}, |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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.
cc @babel/typescript |
`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` + |
There was a problem hiding this comment.
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 }, |
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 allowDeclareFields
6faf79a
to
16e5870
Compare
127754a
to
c188fc4
Compare
Merged to #10545 (not in master yet) |
* Transform TypeScript "declare" fields * Remove multiple spaces * declareFields -> allowDeclareFields
* Transform TypeScript "declare" fields * Remove multiple spaces * declareFields -> allowDeclareFields
* [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
Since there is a breaking change (uninitialized fields are now initialized to undefined), I enabled it behind an option (
allowDeclareFields
). This option is similar touseDefineForClassFields
(microsoft/TypeScript#27644), except that [[Set]] vs [[Define]] is set by theloose
option of the properties transform plugin.Incidentally, this PR fixes #10311 when the plugins are used in the correct order.