Closed IanVS closed 2 years ago
Here's a solution that I think would work, if I'm understanding your problem correctly (if I'm not, my bad). Obviously you want to add error handling and whatever else to turn this into Good Code.
(I'd recommend checking this AST explorer snippet, but I'm including the source code at bottom just in case)
https://astexplorer.net/#/gist/1897ce21b1ec062fabf0389d716a24b9/latest
The two most helpful tools I've found for jscodeshift are ast-explorer and jscodeshift-helper
https://github.com/reergymerej/jscodeshift-helper
The technique I used to figure this out, which is not a half bad problem-solving pattern to use for writing tricky codemods (at least in my opinion)
// jscodeshift can take a parser, like "babel", "babylon", "flow", "ts", or "tsx"
// Read more: https://github.com/facebook/jscodeshift#parser
export const parser = 'tsx'
// Press ctrl+space for code completion
export default function transformer(file, api) {
const j = api.jscodeshift;
return j(file.source)
.find(j.ImportDeclaration)
.replaceWith(nodePath => {
const { node } = nodePath;
node.importKind = "value"
node.specifiers[0]["importKind"] = "type"
return node;
})
.toSource();
}
Thanks, I'll give that a try! I was trying to accomplish this using j.importSpecifier()
to create a new import specifier and then replace the existing one, but I guess your approach here is to just modify the existing one. That makes sense, thanks for the tip.
That said, it still seems like maybe j.importSpecifier()
should be able to create a type import, right? So, I'll leave this feature request open for now.
I think this should be a request for recast (https://github.com/benjamn/recast) rather than jscodeshift, as jscodeshift is built on top of recast and my understanding is that the core AST logic is part of recast.
Probably 80% of all jscodeshift bugs really are issues that need filed are issues that need to be filed with the recast or ast-types projects.
Ah, I thought that since it's a method that is exposed by jscodeshift that there'd be some work required here. I'll take a look at recast, though.
I’d suggest looking at ast-types first, as that’s where most of the builder-ish stuff is. Recast is more responsible for how things are printed out, rememberish states of modified nodes, etc.
Thanks for the guidance. I've taken a crack at a PR to ast-types, since that does indeed seem like where I needed to look. I'll close this out as indeed it wasn't an issue with jscodeshift as y'all suspected.
FWIW, using the example from @ElonVolo, I was able to accomplish what I wanted, and published it in case anyone else finds this issue and is looking for the same kind of thing: https://www.npmjs.com/package/type-import-codemod
There appears to be no
importKind
option that we can provide toImportSpecifierBuilder
(j.importSpecifier()
) in order to create the new style of type import from Typescript 4.5 (https://devblogs.microsoft.com/typescript/announcing-typescript-4-5/#type-on-import-names).I'm trying to write a codemod that changes from the old style of type imports:
import type {MyType} from './types';
to the newer style:
import {type MyType} from './types';
And this doesn't seem possible so far. Or, am I missing it (this is my first codemod).