Repository navigation
JS declarations for an export assigned class expression can conflict with local names #33626
Description
Activity
- addedBugA bug in TypeScriptA bug in TypeScriptDomain: Declaration EmitThe issue relates to the emission of d.ts filesThe issue relates to the emission of d.ts files
on Sep 26, 2019 I have a similar issue with esm default export:
code:import React from "react"; /** * @type {React.FunctionComponent} */ const TabbedShowLayout = ({ classes: classesOverride, className, version, }) => { return ( <div className={className} key={version}> {className} </div> ); }; TabbedShowLayout.defaultProps = { tabs: "default value" }; export default TabbedShowLayout;
emitted declarations:
export default TabbedShowLayout; /** * @type {React.FunctionComponent} */ declare const TabbedShowLayout: React.FunctionComponent; declare namespace TabbedShowLayout { export const defaultProps: Partial<any> | undefined; } import React from "react";
Errors:
Cannot redeclare block-scoped variable 'TabbedShowLayout'.Reacted by Wesley WighamAdditional breakage with javascript:
import React from "react"; import PropTypes from "prop-types" const TabbedShowLayout = ({ }) => { return ( <div /> ); }; TabbedShowLayout.propTypes = { version: PropTypes.number, }; TabbedShowLayout.defaultProps = { tabs: undefined }; export default TabbedShowLayout;
d.ts:export default TabbedShowLayout; declare function TabbedShowLayout({}: {}): JSX.Element; declare namespace TabbedShowLayout { export namespace propTypes { import version = PropTypes.number; export { version }; } export namespace defaultProps { // Cannot export 'undefined'. Only local declarations can be exported from a module export { undefined as tabs }; } // Import declarations in a namespace cannot reference a module.ts(1147) // Cannot find module 'prop-types'.ts(2307) import PropTypes from "prop-types"; }
Reacted by Wesley WighamI'm not sure how common is it to emit invalid types
But i think it will be very useful if the emitter would check the declarations it emits as a fail safe,
and warn the user what something went wrong. maybe prompt to open an issue or so.Is it on the roadmap to 3.7 final?
weswigham commented
on Oct 15, 2019 MemberAuthorMore actionsIt should be, yeah - I'm just on vacation this week, so probably won't progress on it for a bit.
Reacted by Bnaya PeretzI hope this issue won't be forgotten for 3.7 🙏😰
Reacted by Wesley Wighamweswigham commented
on Oct 28, 2019 MemberAuthorMore actionsBnaya Peretz (@Bnaya) I have a build over in #34786 that I'd love if you could give a try.
Reacted by Bnaya PeretzThank you very much!
seems like most of the issues are gonesome of the findings:
import React from 'react'; import PropTypes from 'prop-types'; function Tree({ allowDropOnRoot }) { return <div /> } Tree.propTypes = { classes: PropTypes.object, }; Tree.defaultProps = { classes: {}, parentSource: 'parent_id', }; export default Tree;
emits broken:
export default Tree; declare function Tree({ allowDropOnRoot }: { allowDropOnRoot: any; }): JSX.Element; declare namespace Tree { export namespace propTypes { export const classes: PropTypes.Requireable<object>; } export namespace defaultProps { // Cannot find name 'classes_1' export { classes_1 as classes }; export const parentSource: string; } } import PropTypes from "prop-types"; //# sourceMappingURL=Tree.d.ts.map
When removing the propTypes.classes the problem is gone.
EDIT:
Also it depends on the namespace for theprop-typesmodule and not importing it,
even that on the source, its importing itweswigham commented
on Oct 30, 2019 MemberAuthorMore actionsBnaya Peretz (@Bnaya) there should be another build over in #34786 that also fixes that.
Reacted by Bnaya PeretzWorks!
Thank you!
Probably a related issue:
#34994- locked as resolved and limited conversation to collaborators
on Oct 21, 2025
Per this comment on the PR, the JS declaration emitter currently has a known issue where an export assigned class expression with a name can cause a conflict with another named declaration in the file and produce an invalid declaration file.
So, for example, this:
currently emits along the lines of
(because it reused the anonymous class's name for the hoisted class declaration) which isn't quite right.