Closed
Description
Describe the bug
Version: 4.0.1
Hello! I'm trying to migrate all export default
cases in my codebase to named exports. In order to do so, I'm using the following code:
ts-morph code
Array.from(file.getExportedDeclarations().entries()).forEach(
([id, declaration]) => {
if (id !== 'default') return;
if (
!_.isEqual(declaration.map(x => x.getKind()), [
SyntaxKind.FunctionDeclaration,
]) &&
!_.isEqual(declaration.map(x => x.getKind()), [
SyntaxKind.FunctionDeclaration,
SyntaxKind.Identifier,
])
) {
console.error('Unexpected');
}
const exportAssignment = declaration[0];
const nameTokens = file
.getBaseNameWithoutExtension()
.split('.');
const name = nameTokens[nameTokens.length - 1];
const oldText =
exportAssignment.getPreviousSibling().getKind() ===
SyntaxKind.SingleLineCommentTrivia
? exportAssignment.getText()
: exportAssignment.getFullText();
let newNode;
if (oldText.includes('export default function')) {
newNode = exportAssignment.replaceWithText(
oldText.replace('export default', `export`),
);
} else {
newNode = exportAssignment.replaceWithText(
oldText.replace(
'export default',
`export const ${name} =`,
),
);
}
// 3) Track references
file.getReferencingSourceFiles().forEach(f => {
results.push({
exportFile: file,
importFile: f,
namedExport: { name },
});
});
},
);
Note the acrobatics in order to define oldText
. This is because getFullText()
returns both SingleLineCommentTrivia
and js doc comments, but SingleLineCommentTrivia
exist as sibling nodes while the latter does not. So exportAssignment.replaceWithText(x)
must define x
to include js doc comments but exclude SingleLineCommentTrivia
. This requires testing the previous sibling node. Is this desired? Am I doing it wrong?
Thanks!
Example Default Import 1
// tslint:disable-next-line:no-any only-arrow-functions
export default function Foo() {...}
Example Default Import 2
/** This is Foo */
export default function Foo() {...}
Example Default Import 3
/**
* Prevents an input's `onChange` property from firing on every change. Firing
* on every change makes the input appear laggy. Instead it waits for changes
* to stop happening for a set amount of time, then it triggers an `onChange`.
*/
// tslint:disable-next-line:only-arrow-functions
export function Debounce<Val, BaseProps extends ControlledInput<Val>>(
Component:
| React.ComponentClass<BaseProps>
| React.FunctionComponent<BaseProps>,
) {...}