@samitouri / QOS-React / commits / 05addfc663

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==