Does not work when encounter function component with decorator
See original GitHub issueThe script does not work in the following three situations:
1. Function components with `observer` decorator receive parameters: throw error
// before codemod runs
import { observer } from "mobx-react-lite";
type Props = { id: number };
export const MyComponent: React.FC<Props> = observer((props) => {
return <span>{props.id}</span>
});
// after codemod runs
❯ jscodeshift -t https://raw.githubusercontent.com/gndelia/codemod-replace-react-fc-typescript/main/dist/index.js --extensions=tsx --verbose=2 ./my-component.tsx
Processing 1 files...
Spawning 1 workers...
Sending 1 files to free worker...
TypeError: Cannot read property 'length' of undefined
at addPropsTypeToComponentBody (/private/var/folders/ym/1mprqx7x45bdrz5zt253_0nw0000gn/T/jscodeshift202162-41931-4ws4fq.5drs.js:30:42)
at NodePath.<anonymous> (/private/var/folders/ym/1mprqx7x45bdrz5zt253_0nw0000gn/T/jscodeshift202162-41931-4ws4fq.5drs.js:105:13)
at /Users/bryan/.nvs/node/14.15.5/x64/lib/node_modules/jscodeshift/src/Collection.js:75:36
at Array.forEach (<anonymous>)
at Collection.forEach (/Users/bryan/.nvs/node/14.15.5/x64/lib/node_modules/jscodeshift/src/Collection.js:74:18)
at exports.default (/private/var/folders/ym/1mprqx7x45bdrz5zt253_0nw0000gn/T/jscodeshift202162-41931-4ws4fq.5drs.js:103:14)
at /Users/bryan/.nvs/node/14.15.5/x64/lib/node_modules/jscodeshift/src/Worker.js:157:29
at /Users/bryan/.nvs/node/14.15.5/x64/lib/node_modules/jscodeshift/node_modules/graceful-fs/graceful-fs.js:123:16
at FSReqCallback.readFileAfterClose [as oncomplete] (internal/fs/read_file_context.js:63:3)
SKIP ./header.component.tsx
All done.
Results:
0 errors
0 unmodified
1 skipped
0 ok
Time elapsed: 1.317seconds
1.1 Function components with `observer` decorator do not receive arguments: work normally
// before codemod runs
import { observer } from "mobx-react-lite";
export const MyComponent: React.FC = observer(() => {
return <span>Demo</span>
});
// after codemod runs
export const MyComponent = observer(() => {
return <span>Demo</span>
});
2. When there is intersection types in function component: skip execution
// before codemod runs
import { OtherComponent } from "./other-component";
interface Props {
text: string;
}
export const MyComponent: React.FC<Props> & {
OtherComponent: typeof OtherComponent;
} = ({ text }) => <span>{text}</span>;
MyComponent.OtherComponent = OtherComponent;
// after codemod runs
❯ jscodeshift -t https://raw.githubusercontent.com/gndelia/codemod-replace-react-fc-typescript/main/dist/index.js --extensions=tsx --verbose=0 ./my-component.tsx
Processing 1 files...
Spawning 1 workers...
Sending 1 files to free worker...
All done.
Results:
0 errors
0 unmodified
1 skipped
0 ok
Time elapsed: 0.894seconds
3. React.FunctionComponent will be skipped execution
// before codemod runs
export const MyComponent: React.FunctionComponent = () => <span>Demo</span>;
// after codemod runs
❯ jscodeshift -t https://raw.githubusercontent.com/gndelia/codemod-replace-react-fc-typescript/main/dist/index.js --extensions=tsx --verbose=0 ./my-component.tsx
Processing 1 files...
Spawning 1 workers...
Sending 1 files to free worker...
SKIP ./main.component.tsx
All done.
Results:
0 errors
0 unmodified
1 skipped
0 ok
Time elapsed: 1.300seconds
I tried to modify the script to execute without errors; however, I was unable to add a type definition after the argument while keeping observer().
// before codemod runs
export const MyComponent: React.FC<{ text: string }> = observer(({text}) => <span>{text}</span>)
// after codemod runs
export const MyComponent = observer(({text}) => <span>{text}</span>)
Link to the modified code: https://pastebin.ubuntu.com/p/h5d2gZyWZg/
Issue Analytics
- State:
- Created 2 years ago
- Reactions:1
- Comments:7 (7 by maintainers)
Top Results From Across the Web
Decorators do not work as you might expect
Question: What do you expect to happen? A: Nothing. The decorator doesn't get called because we are not creating an instance of the...
Read more >react-redux's `connect` cannot be used as a decorator: type "is ...
Trying to use react-redux's connect as a class decorator can cause error messages of the form Type 'foo' is not assignable to type...
Read more >react-css-modules with decorators not working - Stack Overflow
I've got react-css-modules working using the function syntax, e.g.. CSSModules(Table, styles). but when using decorators, e.g.. @CSSModules( ...
Read more >Higher-Order Components - React
A higher-order component (HOC) is an advanced technique in React for reusing component logic. HOCs are not part of the React API, per...
Read more >How to use React.memo() to improve performance
Learn how to use React.memo, some common pitfalls you might encounter, and why you shouldn't use React.memo for all your components.
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

I’m glad this small script has been useful for you 🎉 yeah, AST can be tricky, there are soo many scenarios and possible ways to describe similar code that’s complex to consider all the cases. If you manage to solve the problem and submit a PR, I’ll look at it as soon as possible, but if you can’t I’ll try to address it during the next week.
You too have a nice day!
Point 2 solved in #21