Skip to content

Commit 70a1ea5

Browse files
fix(replaceType): handle array syntax (#455)
Co-authored-by: Sebastian "Sebbie" Silbermann <silbermann.sebastian@gmail.com>
1 parent 5614a5f commit 70a1ea5

File tree

3 files changed

+49
-2
lines changed

3 files changed

+49
-2
lines changed

.changeset/wise-icons-wash.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"types-react-codemod": patch
3+
---
4+
5+
Fix a bug when replacing types in shorthand array type notations.
6+
7+
For example, replacing `ReactText` in `ReactText[]` should now result in `(number | string)[]` instead of `number | string[]`.

transforms/__tests__/deprecated-react-child.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,35 @@ test("as type parameter", () => {
121121
createAction<React.ReactElement | number | string>()"
122122
`);
123123
});
124+
125+
test("array type syntax", () => {
126+
expect(
127+
applyTransform(`
128+
import { ReactChild } from 'react';
129+
interface Props {
130+
children?: ReactChild[];
131+
}
132+
`),
133+
).toMatchInlineSnapshot(`
134+
"import { ReactElement } from 'react';
135+
interface Props {
136+
children?: (ReactElement | number | string)[];
137+
}"
138+
`);
139+
});
140+
141+
test("Array generic", () => {
142+
expect(
143+
applyTransform(`
144+
import { ReactChild } from 'react';
145+
interface Props {
146+
children?: Array<ReactChild>;
147+
}
148+
`),
149+
).toMatchInlineSnapshot(`
150+
"import { ReactElement } from 'react';
151+
interface Props {
152+
children?: Array<ReactElement | number | string>;
153+
}"
154+
`);
155+
});

transforms/utils/replaceType.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,16 @@ function replaceReactType(
114114
},
115115
);
116116
for (const typeReferences of sourceIdentifierTypeReferences) {
117-
const changedIdentifiers = typeReferences.replaceWith((path) => {
118-
return buildTargetTypeReference(path.value);
117+
const changedIdentifiers = typeReferences.forEach((path) => {
118+
const targetNode = buildTargetTypeReference(path.value);
119+
if (
120+
targetNode.type === "TSUnionType" &&
121+
path.parentPath.value.type === "TSArrayType"
122+
) {
123+
path.replace(j.tsParenthesizedType(targetNode));
124+
} else {
125+
path.replace(targetNode);
126+
}
119127
});
120128
if (changedIdentifiers.length > 0) {
121129
hasChanges = true;

0 commit comments

Comments
 (0)