Skip to content

Commit 597f983

Browse files
committed
refactor: apply more strict types to ReplaceTransition (#812)
* refactor: apply more strict types to ReplaceTransition * lint: enable the ignoreRestSiblings option of no-unused-vars
1 parent 8a36e76 commit 597f983

File tree

2 files changed

+47
-18
lines changed

2 files changed

+47
-18
lines changed

.eslintrc.yml

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ env:
1111
browser: true
1212
plugins:
1313
- jsx-a11y
14+
rules:
15+
"@typescript-eslint/no-unused-vars":
16+
- error
17+
- ignoreRestSiblings: true
1418

1519
overrides:
1620
- files: www/**/*

src/ReplaceTransition.tsx

+43-18
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,18 @@ type Props = Omit<TransitionProps, 'children'> & {
99
children: [ReactElement<TransitionProps>, ReactElement<TransitionProps>];
1010
};
1111

12+
type LifecycleMethodNames =
13+
| 'onEnter'
14+
| 'onEntering'
15+
| 'onEntered'
16+
| 'onExit'
17+
| 'onExiting'
18+
| 'onExited';
19+
20+
type HandlerArgs = [HTMLElement | boolean, boolean | undefined];
21+
type ChildElement = ReactElement<TransitionProps>;
22+
type ReplaceElements = [ChildElement, ChildElement];
23+
1224
/**
1325
* The `<ReplaceTransition>` component is a specialized `Transition` component
1426
* that animates between two children.
@@ -21,22 +33,31 @@ type Props = Omit<TransitionProps, 'children'> & {
2133
* ```
2234
*/
2335
class ReplaceTransition extends React.Component<Props> {
24-
handleEnter = (...args: any) => this.handleLifecycle('onEnter', 0, args);
25-
handleEntering = (...args: any) =>
36+
handleEnter = (...args: HandlerArgs) =>
37+
this.handleLifecycle('onEnter', 0, args);
38+
handleEntering = (...args: HandlerArgs) =>
2639
this.handleLifecycle('onEntering', 0, args);
27-
handleEntered = (...args: any) => this.handleLifecycle('onEntered', 0, args);
40+
handleEntered = (...args: HandlerArgs) =>
41+
this.handleLifecycle('onEntered', 0, args);
2842

29-
handleExit = (...args: any) => this.handleLifecycle('onExit', 1, args);
30-
handleExiting = (...args: any) => this.handleLifecycle('onExiting', 1, args);
31-
handleExited = (...args: any) => this.handleLifecycle('onExited', 1, args);
43+
handleExit = (...args: HandlerArgs) =>
44+
this.handleLifecycle('onExit', 1, args);
45+
handleExiting = (...args: HandlerArgs) =>
46+
this.handleLifecycle('onExiting', 1, args);
47+
handleExited = (...args: HandlerArgs) =>
48+
this.handleLifecycle('onExited', 1, args);
3249

33-
handleLifecycle(handler: any, idx: number, originalArgs: any) {
50+
handleLifecycle(
51+
handler: LifecycleMethodNames,
52+
idx: number,
53+
originalArgs: HandlerArgs
54+
) {
3455
const { children } = this.props;
3556
// @ts-expect-error FIXME: Type 'string' is not assignable to type 'ReactElement<Props, string | JSXElementConstructor<any>>'.ts(2322)
3657
const child: ChildElement = React.Children.toArray(children)[idx];
3758

59+
// @ts-expect-error FIXME: Type 'false' is not assignable to type '(((boolean | HTMLElement) & (HTMLElement | undefined)) & (HTMLElement | undefined)) & (HTMLElement | undefined)'.ts(2345)
3860
if (child.props[handler]) child.props[handler](...originalArgs);
39-
// @ts-expect-error Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'Readonly<Props> & Readonly<{ children?: ReactNode; }>'.ts(7053)
4061
if (this.props[handler]) {
4162
const maybeNode = child.props.nodeRef
4263
? undefined
@@ -47,15 +68,19 @@ class ReplaceTransition extends React.Component<Props> {
4768
}
4869

4970
render() {
50-
const { children, in: inProp, ...props }: any = this.props;
51-
const [first, second]: any = React.Children.toArray(children);
52-
53-
delete props.onEnter;
54-
delete props.onEntering;
55-
delete props.onEntered;
56-
delete props.onExit;
57-
delete props.onExiting;
58-
delete props.onExited;
71+
const {
72+
children,
73+
in: inProp,
74+
onEnter,
75+
onEntering,
76+
onEntered,
77+
onExit,
78+
onExiting,
79+
onExited,
80+
...props
81+
} = this.props;
82+
// @ts-expect-error FIXME: Target requires 2 element(s) but source may have fewer.ts(2322)
83+
const [first, second]: ReplaceElements = React.Children.toArray(children);
5984

6085
return (
6186
<TransitionGroup {...props}>
@@ -80,7 +105,7 @@ class ReplaceTransition extends React.Component<Props> {
80105
// @ts-expect-error To make TS migration diffs minimum, I've left propTypes here instead of defining a static property
81106
ReplaceTransition.propTypes = {
82107
in: PropTypes.bool.isRequired,
83-
children(props: any, propName: any) {
108+
children(props: any, propName: LifecycleMethodNames) {
84109
if (React.Children.count(props[propName]) !== 2)
85110
return new Error(
86111
`"${propName}" must be exactly two transition components.`

0 commit comments

Comments
 (0)