Skip to content

Commit 68aa03c

Browse files
committed
Inline hoist-non-react-statics to eliminate a dep and help shaking
1 parent bec3fa7 commit 68aa03c

File tree

3 files changed

+138
-2
lines changed

3 files changed

+138
-2
lines changed

src/components/connect.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
/* eslint-disable valid-jsdoc, @typescript-eslint/no-unused-vars */
2-
import hoistStatics from 'hoist-non-react-statics'
32
import type { ComponentType } from 'react'
43
import * as React from 'react'
54
import { isValidElementType, isContextConsumer } from 'react-is'
@@ -31,6 +30,7 @@ import type { Subscription } from '../utils/Subscription'
3130
import { createSubscription } from '../utils/Subscription'
3231
import { useIsomorphicLayoutEffect } from '../utils/useIsomorphicLayoutEffect'
3332
import shallowEqual from '../utils/shallowEqual'
33+
import hoistStatics from '../utils/hoistStatics'
3434
import warning from '../utils/warning'
3535

3636
import type {

src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type {
77

88
import type { Action, UnknownAction, Dispatch } from 'redux'
99

10-
import type { NonReactStatics } from 'hoist-non-react-statics'
10+
import type { NonReactStatics } from './utils/hoistStatics'
1111

1212
import type { ConnectProps } from './components/connect'
1313

src/utils/hoistStatics.ts

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
// Copied directly from:
2+
// https://github.com/mridgway/hoist-non-react-statics/blob/main/src/index.js
3+
// https://unpkg.com/browse/@types/[email protected]/index.d.ts
4+
5+
/**
6+
* Copyright 2015, Yahoo! Inc.
7+
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
8+
*/
9+
import type * as React from 'react'
10+
import { ForwardRef, Memo, isMemo } from 'react-is'
11+
12+
const REACT_STATICS = {
13+
childContextTypes: true,
14+
contextType: true,
15+
contextTypes: true,
16+
defaultProps: true,
17+
displayName: true,
18+
getDefaultProps: true,
19+
getDerivedStateFromError: true,
20+
getDerivedStateFromProps: true,
21+
mixins: true,
22+
propTypes: true,
23+
type: true,
24+
} as const
25+
26+
const KNOWN_STATICS = {
27+
name: true,
28+
length: true,
29+
prototype: true,
30+
caller: true,
31+
callee: true,
32+
arguments: true,
33+
arity: true,
34+
} as const
35+
36+
const FORWARD_REF_STATICS = {
37+
$$typeof: true,
38+
render: true,
39+
defaultProps: true,
40+
displayName: true,
41+
propTypes: true,
42+
} as const
43+
44+
const MEMO_STATICS = {
45+
$$typeof: true,
46+
compare: true,
47+
defaultProps: true,
48+
displayName: true,
49+
propTypes: true,
50+
type: true,
51+
} as const
52+
53+
const TYPE_STATICS = {
54+
[ForwardRef]: FORWARD_REF_STATICS,
55+
[Memo]: MEMO_STATICS,
56+
} as const
57+
58+
function getStatics(component: any) {
59+
// React v16.11 and below
60+
if (isMemo(component)) {
61+
return MEMO_STATICS
62+
}
63+
64+
// React v16.12 and above
65+
return TYPE_STATICS[component['$$typeof']] || REACT_STATICS
66+
}
67+
68+
export type NonReactStatics<
69+
S extends React.ComponentType<any>,
70+
C extends {
71+
[key: string]: true
72+
} = {}
73+
> = {
74+
[key in Exclude<
75+
keyof S,
76+
S extends React.MemoExoticComponent<any>
77+
? keyof typeof MEMO_STATICS | keyof C
78+
: S extends React.ForwardRefExoticComponent<any>
79+
? keyof typeof FORWARD_REF_STATICS | keyof C
80+
: keyof typeof REACT_STATICS | keyof typeof KNOWN_STATICS | keyof C
81+
>]: S[key]
82+
}
83+
84+
const defineProperty = Object.defineProperty
85+
const getOwnPropertyNames = Object.getOwnPropertyNames
86+
const getOwnPropertySymbols = Object.getOwnPropertySymbols
87+
const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor
88+
const getPrototypeOf = Object.getPrototypeOf
89+
const objectPrototype = Object.prototype
90+
91+
export default function hoistNonReactStatics<
92+
T extends React.ComponentType<any>,
93+
S extends React.ComponentType<any>,
94+
C extends {
95+
[key: string]: true
96+
} = {}
97+
>(targetComponent: T, sourceComponent: S): T & NonReactStatics<S, C> {
98+
if (typeof sourceComponent !== 'string') {
99+
// don't hoist over string (html) components
100+
101+
if (objectPrototype) {
102+
const inheritedComponent = getPrototypeOf(sourceComponent)
103+
if (inheritedComponent && inheritedComponent !== objectPrototype) {
104+
hoistNonReactStatics(targetComponent, inheritedComponent)
105+
}
106+
}
107+
108+
let keys: (string | symbol)[] = getOwnPropertyNames(sourceComponent)
109+
110+
if (getOwnPropertySymbols) {
111+
keys = keys.concat(getOwnPropertySymbols(sourceComponent))
112+
}
113+
114+
const targetStatics = getStatics(targetComponent)
115+
const sourceStatics = getStatics(sourceComponent)
116+
117+
for (let i = 0; i < keys.length; ++i) {
118+
const key = keys[i]
119+
if (
120+
!KNOWN_STATICS[key as keyof typeof KNOWN_STATICS] &&
121+
!(sourceStatics && sourceStatics[key as keyof typeof sourceStatics]) &&
122+
!(targetStatics && targetStatics[key as keyof typeof targetStatics])
123+
) {
124+
const descriptor = getOwnPropertyDescriptor(sourceComponent, key)
125+
try {
126+
// Avoid failures from read-only properties
127+
defineProperty(targetComponent, key, descriptor!)
128+
} catch (e) {
129+
// ignore
130+
}
131+
}
132+
}
133+
}
134+
135+
return targetComponent as any
136+
}

0 commit comments

Comments
 (0)