Skip to content

Commit 5409e11

Browse files
committed
Fix or ignore type error
1 parent 99c69be commit 5409e11

14 files changed

+147
-134
lines changed

.babelrc

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
{
2-
"presets": ["@babel/preset-env", "@babel/preset-react", "@babel/preset-flow"]
2+
"presets": [
3+
["@babel/preset-env", { "targets": { "node": "current" } }],
4+
"@babel/preset-react",
5+
"@babel/preset-typescript"
6+
]
37
}

package.json

+4-7
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@
2828
"@babel/cli": "7.15.7",
2929
"@babel/core": "7.15.5",
3030
"@babel/preset-env": "7.15.6",
31-
"@babel/preset-flow": "7.14.5",
3231
"@babel/preset-react": "7.14.5",
32+
"@babel/preset-typescript": "^7.15.0",
3333
"@commitlint/cli": "8.3.5",
3434
"@commitlint/config-angular": "8.3.4",
35-
"@khanacademy/flow-to-ts": "^0.5.2",
3635
"@types/enzyme": "^3.10.9",
3736
"@types/enzyme-adapter-react-16": "^1.0.6",
37+
"@types/jest": "^27.0.2",
3838
"@types/react": "^17.0.26",
3939
"@types/react-is": "^17.0.2",
4040
"babel-eslint": "10.1.0",
@@ -55,7 +55,6 @@
5555
"eslint-plugin-react-hooks": "4.2.0",
5656
"esm": "3.2.25",
5757
"expect": "27.2.3",
58-
"flow-bin": "0.119.1",
5958
"flow-copy-source": "2.0.9",
6059
"husky": "3.1.0",
6160
"jest": "27.2.3",
@@ -72,7 +71,7 @@
7271
"rollup-plugin-node-globals": "1.4.0",
7372
"rollup-plugin-node-resolve": "5.2.0",
7473
"rollup-plugin-sourcemaps": "0.6.3",
75-
"typescript": "4.2.4"
74+
"typescript": "4.4.3"
7675
},
7776
"peerDependencies": {
7877
"react": "^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1",
@@ -84,8 +83,6 @@
8483
"react-is": "17.0.2"
8584
},
8685
"jest": {
87-
"setupFilesAfterEnv": [
88-
"<rootDir>tests/setupTests.js"
89-
]
86+
"setupFilesAfterEnv": ["<rootDir>tests/setupTests.ts"]
9087
}
9188
}

src/AnonymousStatelessComponent.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react'; // eslint-disable-next-line react/display-name
22

3-
export default function (props) {
3+
export default function (props: { children: React.ReactNode }) {
44
const { children } = props; // eslint-disable-line react/prop-types
55

66
return <div>{children}</div>;

src/formatter/createPropFilter.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export default function createPropFilter(
55
if (Array.isArray(filter)) {
66
return (key: string) => filter.indexOf(key) === -1;
77
} else {
8+
// @ts-expect-error: flow to TS
89
return (key: string) => filter(props[key], key);
910
}
1011
}

src/formatter/formatFunction.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,21 @@ import type { Options } from './../options';
22

33
function noRefCheck() {}
44

5-
export const inlineFunction = (fn: any): string =>
5+
type FunctionType = (...args: Array<any>) => any;
6+
7+
export const inlineFunction = (fn: FunctionType): string =>
68
fn
79
.toString()
810
.split('\n')
911
.map((line) => line.trim())
1012
.join('');
11-
export const preserveFunctionLineBreak = (fn: any): string => fn.toString();
13+
14+
export const preserveFunctionLineBreak = (fn: FunctionType): string =>
15+
fn.toString();
16+
1217
const defaultFunctionValue = inlineFunction;
13-
export default (fn: (...args: Array<any>) => any, options: Options): string => {
18+
19+
export default (fn: FunctionType, options: Options): string => {
1420
const { functionValue = defaultFunctionValue, showFunctions } = options;
1521

1622
if (!showFunctions && functionValue === defaultFunctionValue) {

src/formatter/formatReactElementNode.ts

+12-10
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import type { Options } from './../options';
88
import type { ReactElementTreeNode } from './../tree';
99

1010
const compensateMultilineStringElementIndentation = (
11-
element,
11+
element: any,
1212
formattedElement: string,
1313
inline: boolean,
1414
lvl: number,
@@ -33,7 +33,7 @@ const compensateMultilineStringElementIndentation = (
3333
};
3434

3535
const formatOneChildren =
36-
(inline: boolean, lvl: number, options: Options) => (element) =>
36+
(inline: boolean, lvl: number, options: Options) => (element: any) =>
3737
compensateMultilineStringElementIndentation(
3838
element,
3939
formatTreeNode(element, inline, lvl, options),
@@ -42,13 +42,15 @@ const formatOneChildren =
4242
options
4343
);
4444

45-
const onlyPropsWithOriginalValue = (defaultProps, props) => (propName) => {
46-
const haveDefaultValue = Object.keys(defaultProps).includes(propName);
47-
return (
48-
!haveDefaultValue ||
49-
(haveDefaultValue && defaultProps[propName] !== props[propName])
50-
);
51-
};
45+
const onlyPropsWithOriginalValue =
46+
(defaultProps: Record<string, any>, props: Record<string, any>) =>
47+
(propName: string) => {
48+
const haveDefaultValue = Object.keys(defaultProps).includes(propName);
49+
return (
50+
!haveDefaultValue ||
51+
(haveDefaultValue && defaultProps[propName] !== props[propName])
52+
);
53+
};
5254

5355
const isInlineAttributeTooLong = (
5456
attributes: string[],
@@ -117,7 +119,7 @@ export default (
117119
let outInlineAttr = out;
118120
let outMultilineAttr = out;
119121
let containsMultilineAttr = false;
120-
const visibleAttributeNames = [];
122+
const visibleAttributeNames: Array<string> = [];
121123
const propFilter = createPropFilter(props, filterProps);
122124
Object.keys(props)
123125
.filter(propFilter)

src/formatter/formatTreeNode.ts

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import formatReactElementNode from './formatReactElementNode';
22
import formatReactFragmentNode from './formatReactFragmentNode';
33
import type { Options } from './../options';
44
import type { TreeNode } from './../tree';
5+
56
const jsxStopChars = ['<', '>', '{', '}'];
67

78
const shouldBeEscaped = (s: string) =>
@@ -53,5 +54,6 @@ export default (
5354
return formatReactFragmentNode(node, inline, lvl, options);
5455
}
5556

57+
// @ts-expect-error: So should never be executed
5658
throw new TypeError(`Unknow format type "${node.type}"`);
5759
};

src/formatter/sortObject.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ export default function sortObject(value: any): any {
2929
}
3030

3131
if (key === 'current') {
32-
// eslint-disable-next-line no-param-reassign
33-
result[key] = '[Circular]';
32+
// @ts-expect-error: flow to TS
33+
result[key] = '[Circular]'; // eslint-disable-line no-param-reassign
3434
} else {
35-
// eslint-disable-next-line no-param-reassign
36-
result[key] = sortObject(value[key]);
35+
// @ts-expect-error: flow to TS
36+
result[key] = sortObject(value[key]); // eslint-disable-line no-param-reassign
3737
}
3838

3939
return result;

src/index.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import formatTree from './formatter/formatTree';
22
import parseReactElement from './parser/parseReactElement';
3-
import type { Element as ReactElement } from 'react';
3+
import type { ReactElement } from 'react';
44
import type { Options } from './options';
55

66
const reactElementToJsxString = (
7-
element: ReactElement<any>,
7+
element: ReactElement<any> | string | number,
88
{
99
filterProps = [],
1010
showDefaultProps = true,
@@ -16,13 +16,13 @@ const reactElementToJsxString = (
1616
sortProps = true,
1717
maxInlineAttributesLineLength,
1818
displayName,
19-
}: Options = {}
20-
) => {
19+
}: Partial<Options> = {}
20+
): string => {
2121
if (!element) {
2222
throw new Error('react-element-to-jsx-string: Expected a ReactElement');
2323
}
2424

25-
const options = {
25+
const options: Options = {
2626
filterProps,
2727
showDefaultProps,
2828
showFunctions,
@@ -34,10 +34,12 @@ const reactElementToJsxString = (
3434
maxInlineAttributesLineLength,
3535
displayName,
3636
};
37+
3738
return formatTree(parseReactElement(element, options), options);
3839
};
3940

4041
export default reactElementToJsxString;
42+
4143
export {
4244
inlineFunction,
4345
preserveFunctionLineBreak,

src/options.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
import * as React from 'react';
1+
import React from 'react';
2+
23
export type Options = {
34
filterProps: string[];
45
showDefaultProps: boolean;
56
showFunctions: boolean;
6-
functionValue: (...args: Array<any>) => any;
7+
functionValue?: (...args: Array<any>) => any;
78
tabStop: number;
89
useBooleanShorthandSyntax: boolean;
910
useFragmentShortSyntax: boolean;
1011
sortProps: boolean;
12+
1113
maxInlineAttributesLineLength?: number;
12-
displayName?: (element: React.ReactElement<any>) => string;
14+
displayName?: (element: React.ReactElement) => string;
1315
};

src/parser/parseReactElement.ts

+25-18
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Element as ReactElement } from 'react';
1+
import type { ReactElement, ReactNode } from 'react';
22
import React, { Fragment } from 'react';
33
import {
44
ForwardRef,
@@ -23,7 +23,9 @@ import type { TreeNode } from './../tree';
2323

2424
const supportFragment = Boolean(Fragment);
2525

26-
const getFunctionTypeName = (functionType): string => {
26+
const getFunctionTypeName = (
27+
functionType: (...args: Array<any>) => any
28+
): string => {
2729
if (!functionType.name || functionType.name === '_default') {
2830
return 'No Display Name';
2931
}
@@ -49,26 +51,32 @@ const getWrappedComponentDisplayName = (Component: any): string => {
4951

5052
// heavily inspired by:
5153
// https://github.com/facebook/react/blob/3746eaf985dd92f8aa5f5658941d07b6b855e9d9/packages/react-devtools-shared/src/backend/renderer.js#L399-L496
52-
const getReactElementDisplayName = (element: ReactElement<any>): string => {
54+
const getReactElementDisplayName = (element: ReactElement): string => {
5355
switch (true) {
5456
case typeof element.type === 'string':
57+
// @ts-expect-error: flow to TS
5558
return element.type;
5659

5760
case typeof element.type === 'function':
61+
// @ts-expect-error: flow to TS
5862
if (element.type.displayName) {
63+
// @ts-expect-error: flow to TS
5964
return element.type.displayName;
6065
}
6166

67+
// @ts-expect-error: flow to TS
6268
return getFunctionTypeName(element.type);
6369

6470
case isForwardRef(element):
6571
case isMemo(element):
6672
return getWrappedComponentDisplayName(element.type);
6773

6874
case isContextConsumer(element):
75+
// @ts-expect-error: flow to TS
6976
return `${element.type._context.displayName || 'Context'}.Consumer`;
7077

7178
case isContextProvider(element):
79+
// @ts-expect-error: flow to TS
7280
return `${element.type._context.displayName || 'Context'}.Provider`;
7381

7482
case isLazy(element):
@@ -88,19 +96,20 @@ const getReactElementDisplayName = (element: ReactElement<any>): string => {
8896
}
8997
};
9098

91-
const noChildren = (propsValue, propName) => propName !== 'children';
99+
const noChildren = (propsValue: unknown, propName: string) =>
100+
propName !== 'children';
92101

93-
const onlyMeaningfulChildren = (children): boolean =>
102+
const onlyMeaningfulChildren = (children: ReactNode): boolean =>
94103
children !== true &&
95104
children !== false &&
96105
children !== null &&
97106
children !== '';
98107

99108
const filterProps = (
100-
originalProps: {},
101-
cb: (arg0: any, arg1: string) => boolean
102-
) => {
103-
const filteredProps = {};
109+
originalProps: Record<string, any>,
110+
cb: (propsValue: any, propsName: string) => boolean
111+
): Record<string, any> => {
112+
const filteredProps: Record<string, any> = {};
104113
Object.keys(originalProps)
105114
.filter((key) => cb(originalProps[key], key))
106115
.forEach((key) => (filteredProps[key] = originalProps[key]));
@@ -126,7 +135,9 @@ const parseReactElement = (
126135
const displayName = displayNameFn(element);
127136
const props = filterProps(element.props, noChildren);
128137

138+
// @ts-expect-error: flow to TS
129139
if (element.ref !== null) {
140+
// @ts-expect-error: flow to TS
130141
props.ref = element.ref;
131142
}
132143

@@ -137,21 +148,17 @@ const parseReactElement = (
137148
props.key = key;
138149
}
139150

151+
// @ts-expect-error: flow to TS
140152
const defaultProps = filterProps(element.type.defaultProps || {}, noChildren);
141-
const childrens = React.Children.toArray(element.props.children)
153+
const children = React.Children.toArray(element.props.children)
142154
.filter(onlyMeaningfulChildren)
143-
.map((child) => parseReactElement(child, options));
155+
.map((child: ReactElement<any>) => parseReactElement(child, options));
144156

145157
if (supportFragment && element.type === Fragment) {
146-
return createReactFragmentTreeNode(key, childrens);
158+
return createReactFragmentTreeNode(key, children);
147159
}
148160

149-
return createReactElementTreeNode(
150-
displayName,
151-
props,
152-
defaultProps,
153-
childrens
154-
);
161+
return createReactElementTreeNode(displayName, props, defaultProps, children);
155162
};
156163

157164
export default parseReactElement;

0 commit comments

Comments
 (0)