Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit cdf65b9

Browse files
committedFeb 5, 2025
fix: fix remove-forward-ref codemod error
1 parent 043fc45 commit cdf65b9

File tree

2 files changed

+36
-33
lines changed

2 files changed

+36
-33
lines changed
 

Diff for: ‎transforms/remove-forward-ref.ts

+33-28
Original file line numberDiff line numberDiff line change
@@ -8,46 +8,47 @@ import type {
88
JSCodeshift,
99
TSTypeLiteral,
1010
TSTypeReference,
11-
} from 'jscodeshift';
11+
TSTypeParameterInstantiation,
12+
} from "jscodeshift";
1213

1314
// Props & { ref: React.RefObject<Ref>}
1415
const buildPropsAndRefIntersectionTypeAnnotation = (
1516
j: JSCodeshift,
1617
propType: TSTypeReference | TSTypeLiteral,
17-
refType: TSTypeReference | TSTypeLiteral | null,
18+
refType: TSTypeReference | TSTypeLiteral | null
1819
) =>
1920
j.tsTypeAnnotation(
2021
j.tsIntersectionType([
2122
propType,
2223
j.tsTypeLiteral([
2324
j.tsPropertySignature.from({
24-
key: j.identifier('ref'),
25+
key: j.identifier("ref"),
2526
typeAnnotation: j.tsTypeAnnotation(
2627
j.tsTypeReference.from({
2728
typeName: j.tsQualifiedName(
28-
j.identifier('React'),
29-
j.identifier('RefObject'),
29+
j.identifier("React"),
30+
j.identifier("RefObject")
3031
),
3132
typeParameters: j.tsTypeParameterInstantiation([
3233
refType === null ? j.tsUnknownKeyword() : refType,
3334
]),
34-
}),
35+
})
3536
),
3637
}),
3738
]),
38-
]),
39+
])
3940
);
4041

4142
// { ref: refName, ...propsName }
4243
const buildRefAndPropsObjectPattern = (
4344
j: JSCodeshift,
4445
refArgName: string,
45-
propArgName: string,
46+
propArgName: string
4647
) =>
4748
j.objectPattern([
4849
j.objectProperty.from({
4950
shorthand: true,
50-
key: j.identifier('ref'),
51+
key: j.identifier("ref"),
5152
value: j.identifier(refArgName),
5253
}),
5354
j.restProperty(j.identifier(propArgName)),
@@ -65,7 +66,7 @@ const getRefTypeFromRefArg = (j: JSCodeshift, refArg: Identifier) => {
6566

6667
const { right } = typeReference.typeName;
6768

68-
if (!j.Identifier.check(right) || right.name === 'forwardedRef') {
69+
if (!j.Identifier.check(right) || right.name === "forwardedRef") {
6970
return null;
7071
}
7172

@@ -80,7 +81,7 @@ const getRefTypeFromRefArg = (j: JSCodeshift, refArg: Identifier) => {
8081

8182
const getForwardRefRenderFunction = (
8283
j: JSCodeshift,
83-
callExpression: CallExpression,
84+
callExpression: CallExpression
8485
): FunctionExpression | ArrowFunctionExpression | null => {
8586
const [renderFunction] = callExpression.arguments;
8687

@@ -96,7 +97,7 @@ const getForwardRefRenderFunction = (
9697

9798
const isLiteralOrReference = (
9899
j: JSCodeshift,
99-
type: unknown,
100+
type: unknown
100101
): type is TSTypeReference | TSTypeLiteral => {
101102
return j.TSTypeReference.check(type) || j.TSTypeLiteral.check(type);
102103
};
@@ -113,14 +114,14 @@ export default function transform(file: FileInfo, api: API) {
113114

114115
root
115116
.find(j.ImportDeclaration, {
116-
source: { value: 'react' },
117+
source: { value: "react" },
117118
})
118119
.forEach((path) => {
119120
path.value.specifiers?.forEach((specifier) => {
120121
// named import
121122
if (
122123
j.ImportSpecifier.check(specifier) &&
123-
specifier.imported.name === 'forwardRef'
124+
specifier.imported.name === "forwardRef"
124125
) {
125126
reactForwardRefImportLocalName = specifier.local?.name ?? null;
126127
}
@@ -152,7 +153,7 @@ export default function transform(file: FileInfo, api: API) {
152153
j.Identifier.check(callee.object) &&
153154
callee.object.name === reactDefaultImportName &&
154155
j.Identifier.check(callee.property) &&
155-
callee.property.name === 'forwardRef'
156+
callee.property.name === "forwardRef"
156157
) {
157158
return true;
158159
}
@@ -164,11 +165,11 @@ export default function transform(file: FileInfo, api: API) {
164165

165166
const renderFunction = getForwardRefRenderFunction(
166167
j,
167-
callExpressionPath.node,
168+
callExpressionPath.node
168169
);
169170

170171
if (renderFunction === null) {
171-
console.warn('Could not detect render function.');
172+
console.warn("Could not detect render function.");
172173

173174
return originalCallExpression;
174175
}
@@ -179,7 +180,7 @@ export default function transform(file: FileInfo, api: API) {
179180
!j.Identifier.check(refArg) ||
180181
!(j.Identifier.check(propsArg) || j.ObjectPattern.check(propsArg))
181182
) {
182-
console.warn('Could not detect ref or props arguments.');
183+
console.warn("Could not detect ref or props arguments.");
183184

184185
return originalCallExpression;
185186
}
@@ -196,9 +197,9 @@ export default function transform(file: FileInfo, api: API) {
196197
propsArg.properties.unshift(
197198
j.objectProperty.from({
198199
shorthand: true,
199-
key: j.identifier('ref'),
200+
key: j.identifier("ref"),
200201
value: j.identifier(refArgName),
201-
}),
202+
})
202203
);
203204

204205
isDirty = true;
@@ -209,7 +210,7 @@ export default function transform(file: FileInfo, api: API) {
209210
renderFunction.params[0] = buildRefAndPropsObjectPattern(
210211
j,
211212
refArg.name,
212-
propsArg.name,
213+
propsArg.name
213214
);
214215

215216
isDirty = true;
@@ -222,13 +223,13 @@ export default function transform(file: FileInfo, api: API) {
222223
if (
223224
isLiteralOrReference(j, propsArgTypeReference) &&
224225
renderFunction.params?.[0] &&
225-
'typeAnnotation' in renderFunction.params[0]
226+
"typeAnnotation" in renderFunction.params[0]
226227
) {
227228
renderFunction.params[0].typeAnnotation =
228229
buildPropsAndRefIntersectionTypeAnnotation(
229230
j,
230231
propsArgTypeReference,
231-
refArgTypeReference,
232+
refArgTypeReference
232233
);
233234
isDirty = true;
234235
}
@@ -237,14 +238,18 @@ export default function transform(file: FileInfo, api: API) {
237238
* Transform ts types: forwardRef type arguments are used
238239
*/
239240

240-
const typeParameters = callExpressionPath.node.typeParameters;
241+
const typeParameters = (
242+
callExpressionPath.node as CallExpression & {
243+
typeParameters?: TSTypeParameterInstantiation;
244+
}
245+
).typeParameters;
241246

242247
// if typeParameters are used in forwardRef generic, reuse them to annotate props type
243248
// forwardRef<Ref, Props>((props) => { ... }) ====> (props: Props & { ref: React.RefObject<Ref> }) => { ... }
244249
if (
245250
j.TSTypeParameterInstantiation.check(typeParameters) &&
246251
renderFunction.params?.[0] &&
247-
'typeAnnotation' in renderFunction.params[0]
252+
"typeAnnotation" in renderFunction.params[0]
248253
) {
249254
const [refType, propType] = typeParameters.params;
250255

@@ -269,20 +274,20 @@ export default function transform(file: FileInfo, api: API) {
269274
root
270275
.find(j.ImportDeclaration, {
271276
source: {
272-
value: 'react',
277+
value: "react",
273278
},
274279
})
275280
.forEach((importDeclarationPath) => {
276281
const { specifiers, importKind } = importDeclarationPath.node;
277282

278-
if (importKind !== 'value') {
283+
if (importKind !== "value") {
279284
return;
280285
}
281286

282287
const specifiersWithoutForwardRef =
283288
specifiers?.filter(
284289
(s) =>
285-
!j.ImportSpecifier.check(s) || s.imported.name !== 'forwardRef',
290+
!j.ImportSpecifier.check(s) || s.imported.name !== "forwardRef"
286291
) ?? [];
287292

288293
if (specifiersWithoutForwardRef.length === 0) {

Diff for: ‎tsconfig.json

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
{
22
"compilerOptions": {
3-
"moduleDetection": "force",
3+
"moduleDetection": "force",
44
"target": "ES2015"
55
},
6-
"references": [
7-
{ "path": "./tsconfig.codemod.json" }
8-
]
9-
}
6+
"references": [{ "path": "./tsconfig.codemod.json" }]
7+
}

0 commit comments

Comments
 (0)
Please sign in to comment.