Update Flow to 0.266 (#34271)
- replace `$ElementType` and `$PropertyType` with `T[K]` accesses. - Use component types
Jan Kassens committed
Aug 22, 2025 at 15:46 UTC
05addfc6631ca72099631476b0a1592753858d30
25 files changed
+76
-86
.eslintrc.js
-4
@@ -547,12 +547,10 @@ module.exports = {
547
},
548
549
globals: {
550
- $ElementType: 'readonly',
550
$Flow$ModuleRef: 'readonly',
551
$FlowFixMe: 'readonly',
552
$Keys: 'readonly',
553
$NonMaybeType: 'readonly',
555
- $PropertyType: 'readonly',
554
$ReadOnly: 'readonly',
555
$ReadOnlyArray: 'readonly',
556
$ArrayBufferView: 'readonly',
@@ -586,9 +584,7 @@ module.exports = {
584
NavigateEvent: 'readonly',
585
PropagationPhases: 'readonly',
586
PropertyDescriptor: 'readonly',
589
- React$AbstractComponent: 'readonly',
587
React$Component: 'readonly',
591
- React$ComponentType: 'readonly',
588
React$Config: 'readonly',
589
React$Context: 'readonly',
590
React$Element: 'readonly',
package.json
+2
-2
@@ -74,8 +74,8 @@
74
"eslint-plugin-react-internal": "link:./scripts/eslint-rules",
75
"fbjs-scripts": "^3.0.1",
76
"filesize": "^6.0.1",
77
- "flow-bin": "^0.265",
78
- "flow-remove-types": "^2.265",
77
+ "flow-bin": "^0.266",
78
+ "flow-remove-types": "^2.266",
79
"flow-typed": "^4.1.1",
80
"glob": "^7.1.6",
81
"glob-stream": "^6.1.0",
packages/react-devtools-inline/src/frontend.js
+1
-1
@@ -52,7 +52,7 @@ export function initialize(
52
bridge?: FrontendBridge,
53
store?: Store,
54
} = {},
55
-): React.ComponentType<Props> {
55
+): component(...props: Props) {
56
if (bridge == null) {
57
bridge = createBridge(contentWindow);
58
}
packages/react-devtools-shared/src/bridge.js
+1
-1
@@ -314,7 +314,7 @@ class Bridge<
314
315
send<EventName: $Keys<OutgoingEvents>>(
316
event: EventName,
317
- ...payload: $ElementType<OutgoingEvents, EventName>
317
+ ...payload: OutgoingEvents[EventName]
318
) {
319
if (this._isShutdown) {
320
console.warn(
packages/react-devtools-shared/src/devtools/views/Components/Components.js
+1
-1
@@ -235,4 +235,4 @@ function setResizeCSSVariable(
235
}
236
}
237
238
-export default (portaledContent(Components): React$ComponentType<{}>);
238
+export default (portaledContent(Components): component());
packages/react-devtools-shared/src/devtools/views/Components/InspectedElementHooksTree.js
+3
-3
@@ -386,6 +386,6 @@ function HookView({
386
}
387
}
388
389
-export default (React.memo(
390
- InspectedElementHooksTree,
391
-): React.ComponentType<HookViewProps>);
389
+export default (React.memo(InspectedElementHooksTree): component(
390
+ ...props: HookViewProps
391
+));
packages/react-devtools-shared/src/devtools/views/Editor/EditorPane.js
+1
-1
@@ -115,4 +115,4 @@ function EditorPane({selectedSource}: Props) {
115
</div>
116
);
117
}
118
-export default (portaledContent(EditorPane): React$ComponentType<{}>);
118
+export default (portaledContent(EditorPane): component());
packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraphListItem.js
+3
-4
@@ -132,7 +132,6 @@ function CommitFlamegraphListItem({data, index, style}: Props): React.Node {
132
);
133
}
134
135
-export default (memo(
136
- CommitFlamegraphListItem,
137
- areEqual,
138
-): React.ComponentType<Props>);
135
+export default (memo(CommitFlamegraphListItem, areEqual): component(
136
+ ...props: Props
137
+));
packages/react-devtools-shared/src/devtools/views/Profiler/CommitRankedListItem.js
+3
-4
@@ -79,7 +79,6 @@ function CommitRankedListItem({data, index, style}: Props) {
79
);
80
}
81
82
-export default (memo(
83
- CommitRankedListItem,
84
- areEqual,
85
-): React.ComponentType<Props>);
82
+export default (memo(CommitRankedListItem, areEqual): component(
83
+ ...props: Props
84
+));
packages/react-devtools-shared/src/devtools/views/Profiler/HookChangeSummary.js
+34
-30
@@ -38,34 +38,38 @@ type HookProps = {
38
hookNames: Map<string, string> | null,
39
};
40
41
-const Hook: React.AbstractComponent<HookProps> = memo(({hook, hookNames}) => {
42
- const hookSource = hook.hookSource;
43
- const hookName = useMemo(() => {
44
- if (!hookSource || !hookNames) return null;
45
- const key = getHookSourceLocationKey(hookSource);
46
- return hookNames.get(key) || null;
47
- }, [hookSource, hookNames]);
48
-
49
- return (
50
- <ul className={styles.Hook}>
51
- <li>
52
- {hook.id !== null && (
53
- <span className={styles.PrimitiveHookNumber}>
54
- {String(hook.id + 1)}
41
+const Hook: component(...props: HookProps) = memo(
42
+ ({hook, hookNames}: HookProps) => {
43
+ const hookSource = hook.hookSource;
44
+ const hookName = useMemo(() => {
45
+ if (!hookSource || !hookNames) return null;
46
+ const key = getHookSourceLocationKey(hookSource);
47
+ return hookNames.get(key) || null;
48
+ }, [hookSource, hookNames]);
49
+
50
+ return (
51
+ <ul className={styles.Hook}>
52
+ <li>
53
+ {hook.id !== null && (
54
+ <span className={styles.PrimitiveHookNumber}>
55
+ {String(hook.id + 1)}
56
+ </span>
57
+ )}
58
+ <span
59
+ className={
60
+ hook.id !== null ? styles.PrimitiveHookName : styles.Name
61
+ }>
62
+ {hook.name}
63
+ {hookName && <span className={styles.HookName}>({hookName})</span>}
64
</span>
56
- )}
57
- <span
58
- className={hook.id !== null ? styles.PrimitiveHookName : styles.Name}>
59
- {hook.name}
60
- {hookName && <span className={styles.HookName}>({hookName})</span>}
61
- </span>
62
- {hook.subHooks?.map((subHook, index) => (
63
- <Hook key={hook.id} hook={subHook} hookNames={hookNames} />
64
- ))}
65
- </li>
66
- </ul>
67
- );
68
-});
65
+ {hook.subHooks?.map((subHook, index) => (
66
+ <Hook key={hook.id} hook={subHook} hookNames={hookNames} />
67
+ ))}
68
+ </li>
69
+ </ul>
70
+ );
71
+ },
72
+);
73
74
const shouldKeepHook = (
75
hook: HooksNode,
@@ -105,12 +109,12 @@ const filterHooks = (
109
110
type Props = {|
111
fiberID: number,
108
- hooks: $PropertyType<ChangeDescription, 'hooks'>,
109
- state: $PropertyType<ChangeDescription, 'state'>,
112
+ hooks: ChangeDescription['hooks'],
113
+ state: ChangeDescription['state'],
114
displayMode?: 'detailed' | 'compact',
115
|};
116
113
-const HookChangeSummary: React.AbstractComponent<Props> = memo(
117
+const HookChangeSummary: component(...props: Props) = memo(
118
({hooks, fiberID, state, displayMode = 'detailed'}: Props) => {
119
const {parseHookNames, toggleParseHookNames, inspectedElement} = useContext(
120
InspectedElementContext,
packages/react-devtools-shared/src/devtools/views/Profiler/Profiler.js
+1
-1
@@ -190,4 +190,4 @@ const tabsWithTimeline = [
190
},
191
];
192
193
-export default (portaledContent(Profiler): React.ComponentType<{}>);
193
+export default (portaledContent(Profiler): component());
packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitListItem.js
+3
-4
@@ -96,7 +96,6 @@ function SnapshotCommitListItem({data: itemData, index, style}: Props) {
96
);
97
}
98
99
-export default (memo(
100
- SnapshotCommitListItem,
101
- areEqual,
102
-): React.ComponentType<Props>);
99
+export default (memo(SnapshotCommitListItem, areEqual): component(
100
+ ...props: Props
101
+));
packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseTab.js
+1
-1
@@ -437,4 +437,4 @@ function setResizeCSSVariable(
437
}
438
}
439
440
-export default (portaledContent(SuspenseTab): React$ComponentType<{}>);
440
+export default (portaledContent(SuspenseTab): component());
packages/react-devtools-shared/src/devtools/views/portaledContent.js
+2
-2
@@ -17,8 +17,8 @@ import ThemeProvider from './ThemeProvider';
17
export type Props = {portalContainer?: Element, ...};
18
19
export default function portaledContent(
20
- Component: React$ComponentType<any>,
21
-): React$ComponentType<any> {
20
+ Component: component(...props: any),
21
+): component(...props: any) {
22
return function PortaledContent({portalContainer, ...rest}: Props) {
23
const store = useContext(StoreContext);
24
packages/react-devtools-shared/src/events.js
+2
-5
@@ -12,7 +12,7 @@ export default class EventEmitter<Events: Object> {
12
13
addListener<Event: $Keys<Events>>(
14
event: Event,
15
- listener: (...$ElementType<Events, Event>) => any,
15
+ listener: (...Events[Event]) => any,
16
): void {
17
const listeners = this.listenersMap.get(event);
18
if (listeners === undefined) {
@@ -25,10 +25,7 @@ export default class EventEmitter<Events: Object> {
25
}
26
}
27
28
- emit<Event: $Keys<Events>>(
29
- event: Event,
30
- ...args: $ElementType<Events, Event>
31
- ): void {
28
+ emit<Event: $Keys<Events>>(event: Event, ...args: Events[Event]): void {
29
const listeners = this.listenersMap.get(event);
30
if (listeners !== undefined) {
31
if (listeners.length === 1) {
packages/react-devtools-shared/src/hydration.js
+3
-3
@@ -133,7 +133,7 @@ export function dehydrate(
133
path: Array<string | number>,
134
isPathAllowed: (path: Array<string | number>) => boolean,
135
level: number = 0,
136
-): $PropertyType<DehydratedData, 'data'> {
136
+): DehydratedData['data'] {
137
const type = getDataType(data);
138
139
let isPathAllowedCheck;
@@ -479,7 +479,7 @@ export function dehydrate(
479
return createDehydrated(type, true, data, cleaned, path);
480
} else {
481
const object: {
482
- [string]: $PropertyType<DehydratedData, 'data'>,
482
+ [string]: DehydratedData['data'],
483
} = {};
484
getAllEnumerableKeys(data).forEach(key => {
485
const name = key.toString();
@@ -616,7 +616,7 @@ function dehydrateKey(
616
path: Array<string | number>,
617
isPathAllowed: (path: Array<string | number>) => boolean,
618
level: number = 0,
619
-): $PropertyType<DehydratedData, 'data'> {
619
+): DehydratedData['data'] {
620
try {
621
return dehydrate(
622
parent[key],
packages/react-devtools-shell/src/app/ToDoList/ListItem.js
+1
-1
@@ -46,4 +46,4 @@ function ListItem({item, removeItem, toggleItem}: Props) {
46
);
47
}
48
49
-export default (memo(ListItem): React.ComponentType<Props>);
49
+export default (memo(ListItem): component(...props: Props));
packages/react-devtools-timeline/src/import-worker/preprocessData.js
+4
-4
@@ -123,7 +123,7 @@ function updateLaneToLabelMap(
123
124
let profilerVersion = null;
125
126
-function getLastType(stack: $PropertyType<ProcessorState, 'measureStack'>) {
126
+function getLastType(stack: ProcessorState['measureStack']) {
127
if (stack.length > 0) {
128
const {type} = stack[stack.length - 1];
129
return type;
@@ -131,7 +131,7 @@ function getLastType(stack: $PropertyType<ProcessorState, 'measureStack'>) {
131
return null;
132
}
133
134
-function getDepth(stack: $PropertyType<ProcessorState, 'measureStack'>) {
134
+function getDepth(stack: ProcessorState['measureStack']) {
135
if (stack.length > 0) {
136
const {depth, type} = stack[stack.length - 1];
137
return type === 'render-idle' ? depth : depth + 1;
@@ -180,7 +180,7 @@ function markWorkCompleted(
180
type: ReactMeasureType,
181
stopTime: Milliseconds,
182
currentProfilerData: TimelineData,
183
- stack: $PropertyType<ProcessorState, 'measureStack'>,
183
+ stack: ProcessorState['measureStack'],
184
) {
185
if (stack.length === 0) {
186
console.error(
@@ -214,7 +214,7 @@ function markWorkCompleted(
214
215
function throwIfIncomplete(
216
type: ReactMeasureType,
217
- stack: $PropertyType<ProcessorState, 'measureStack'>,
217
+ stack: ProcessorState['measureStack'],
218
) {
219
const lastIndex = stack.length - 1;
220
if (lastIndex >= 0) {
packages/react-devtools-timeline/src/types.js
+1
-1
@@ -79,7 +79,7 @@ export type SchedulingEvent =
79
| ReactScheduleRenderEvent
80
| ReactScheduleStateUpdateEvent
81
| ReactScheduleForceUpdateEvent;
82
-export type SchedulingEventType = $PropertyType<SchedulingEvent, 'type'>;
82
+export type SchedulingEventType = SchedulingEvent['type'];
83
84
export type ReactMeasureType =
85
| 'commit'
packages/react-markup/src/ReactMarkupServer.js
+1
-1
@@ -47,7 +47,7 @@ import {
47
type ReactMarkupNodeList =
48
// This is the intersection of ReactNodeList and ReactClientValue minus
49
// Client/ServerReferences.
50
- | React$Element<React$ComponentType<any>>
50
+ | component(...props: any)
51
| LazyComponent<ReactMarkupNodeList, any>
52
| React$Element<string>
53
| string
packages/react-reconciler/src/ReactTestSelectors.js
+2
-2
@@ -48,7 +48,7 @@ type Type = symbol | number;
48
49
type ComponentSelector = {
50
$$typeof: Type,
51
- value: React$ComponentType<empty>,
51
+ value: component(),
52
};
53
54
type HasPseudoClassSelector = {
@@ -79,7 +79,7 @@ type Selector =
79
| TestNameSelector;
80
81
export function createComponentSelector(
82
- component: React$ComponentType<empty>,
82
+ component: component(),
83
): ComponentSelector {
84
return {
85
$$typeof: COMPONENT_TYPE,
packages/react-server/src/ReactFlightServer.js
+1
-1
@@ -476,7 +476,7 @@ type ReactJSONValue =
476
// Serializable values
477
export type ReactClientValue =
478
// Server Elements and Lazy Components are unwrapped on the Server
479
- | React$Element<React$ComponentType<any>>
479
+ | React$Element<component(...props: any)>
480
| LazyComponent<ReactClientValue, any>
481
// References are passed by their value
482
| ClientReference<any>
packages/react/index.development.js
-2
@@ -8,8 +8,6 @@
8
*/
9
10
// Keep in sync with https://github.com/facebook/flow/blob/main/lib/react.js
11
-export type ComponentType<-P> = React$ComponentType<P>;
12
-export type AbstractComponent<-Config> = React$AbstractComponent<Config>;
11
export type ElementType = React$ElementType;
12
export type Element<+C> = React$Element<C>;
13
export type Key = React$Key;
packages/react/index.js
-2
@@ -8,8 +8,6 @@
8
*/
9
10
// Keep in sync with https://github.com/facebook/flow/blob/main/lib/react.js
11
-export type ComponentType<-P> = React$ComponentType<P>;
12
-export type AbstractComponent<-Config> = React$AbstractComponent<Config>;
11
export type ElementType = React$ElementType;
12
export type Element<+C> = React$Element<C>;
13
export type MixedElement = React$Element<ElementType>;
yarn.lock
+5
-5
@@ -9298,12 +9298,12 @@ flatted@^3.2.9:
9298
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a"
9299
integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==
9300
9301
-flow-bin@^0.265:
9302
- version "0.265.3"
9303
- resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.265.3.tgz#cbaad2115f4622e34920981dc79949824c27f421"
9304
- integrity sha512-08PjO2kjuQxy8MxYJNCzmgRpAe1uqTf7kQ+U32QTavRzTD/7IJASYKFEEvCkVNHlhSy8CTJsN+AQdHsXVqChIw==
9301
+flow-bin@^0.266:
9302
+ version "0.266.1"
9303
+ resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.266.1.tgz#8939be6fbd681c4ef8dc4873b22f4b79be76cb0a"
9304
+ integrity sha512-c1lg1E8SDcuPSkrOeH0JTcNKMZOzXvqX2DuuXJ0amZec15uyuIi8QlGTO3OzYssMT/kwFdo5vviJqSUI/BNFbw==
9305
9306
-flow-remove-types@^2.265:
9306
+flow-remove-types@^2.266:
9307
version "2.279.0"
9308
resolved "https://registry.yarnpkg.com/flow-remove-types/-/flow-remove-types-2.279.0.tgz#3a3388d9158eba0f82c40d80d31d9640b883a3f5"
9309
integrity sha512-bPFloMR/A2b/r/sIsf7Ix0LaMicCJNjwhXc4xEEQVzJCIz5u7C7XDaEOXOiqveKlCYK7DcBNn6R01Cbbc9gsYA==