From 847ae94bd2941936e1a1036d34eb0db9cb0e764b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szymon=20Kozio=C5=82?= Date: Tue, 14 Jul 2026 13:41:10 +0200 Subject: [PATCH 1/2] Add TypeScript declarations for requestIdleCallback and cancelIdleCallback requestIdleCallback and cancelIdleCallback exist at runtime on both architectures and are declared in the Flow libdefs, but the public TypeScript types never included them. React Native projects compile without lib: ["dom"], so the API was invisible to TypeScript users - Added the declarations to src/types/globals.d.ts - Add type tests in __typetests__/globals.tsx --- .../react-native/__typetests__/globals.tsx | 19 +++++++++++++++++++ packages/react-native/src/types/globals.d.ts | 10 ++++++++++ 2 files changed, 29 insertions(+) diff --git a/packages/react-native/__typetests__/globals.tsx b/packages/react-native/__typetests__/globals.tsx index 831a67b7297f..2a45a3524600 100644 --- a/packages/react-native/__typetests__/globals.tsx +++ b/packages/react-native/__typetests__/globals.tsx @@ -137,6 +137,25 @@ function testRequestAnimationFrame(){ ); } +function testRequestIdleCallback() { + let handle = requestIdleCallback(deadline => { + const didTimeout: boolean = deadline.didTimeout; + const remaining: number = deadline.timeRemaining(); + console.log(didTimeout, remaining); + }); + cancelIdleCallback(handle); + + handle = requestIdleCallback(noop, { timeout: 100 }); + cancelIdleCallback(handle); + + // @ts-expect-error + requestIdleCallback(noop, { timeout: 'wrong-type' }); + + // handle is opaque: object on New Architecture, number on legacy + // @ts-expect-error + const handleIsNotNumber: number = requestIdleCallback(noop); +} + const fetchCopy: WindowOrWorkerGlobalScope['fetch'] = fetch; const myHeaders = new Headers(); diff --git a/packages/react-native/src/types/globals.d.ts b/packages/react-native/src/types/globals.d.ts index 98f824c62b84..d1e44db30dbc 100644 --- a/packages/react-native/src/types/globals.d.ts +++ b/packages/react-native/src/types/globals.d.ts @@ -125,6 +125,16 @@ declare global { function cancelAnimationFrame(handle: number | null | undefined): void; function requestAnimationFrame(callback: (time: number) => void): number; + type IdleCallbackID = unknown; + function requestIdleCallback( + callback: (deadline: { + didTimeout: boolean; + timeRemaining: () => number; + }) => void, + options?: {timeout: number}, + ): IdleCallbackID; + function cancelIdleCallback(handle: IdleCallbackID): void; + function fetchBundle( bundleId: number, callback: (error?: Error | null) => void, From dcbca376db72cd81acb68598557cd5e1e181e88f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szymon=20Kozio=C5=82?= Date: Tue, 14 Jul 2026 16:58:59 +0200 Subject: [PATCH 2/2] use number for requestIdleCallback handle --- packages/react-native/__typetests__/globals.tsx | 6 ++++-- packages/react-native/src/types/globals.d.ts | 5 ++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/react-native/__typetests__/globals.tsx b/packages/react-native/__typetests__/globals.tsx index 2a45a3524600..ec9be0164163 100644 --- a/packages/react-native/__typetests__/globals.tsx +++ b/packages/react-native/__typetests__/globals.tsx @@ -138,6 +138,9 @@ function testRequestAnimationFrame(){ } function testRequestIdleCallback() { + cancelIdleCallback(null); + cancelIdleCallback(undefined); + let handle = requestIdleCallback(deadline => { const didTimeout: boolean = deadline.didTimeout; const remaining: number = deadline.timeRemaining(); @@ -151,9 +154,8 @@ function testRequestIdleCallback() { // @ts-expect-error requestIdleCallback(noop, { timeout: 'wrong-type' }); - // handle is opaque: object on New Architecture, number on legacy // @ts-expect-error - const handleIsNotNumber: number = requestIdleCallback(noop); + cancelIdleCallback('wrong-type'); } const fetchCopy: WindowOrWorkerGlobalScope['fetch'] = fetch; diff --git a/packages/react-native/src/types/globals.d.ts b/packages/react-native/src/types/globals.d.ts index d1e44db30dbc..c5c9617fe02c 100644 --- a/packages/react-native/src/types/globals.d.ts +++ b/packages/react-native/src/types/globals.d.ts @@ -125,15 +125,14 @@ declare global { function cancelAnimationFrame(handle: number | null | undefined): void; function requestAnimationFrame(callback: (time: number) => void): number; - type IdleCallbackID = unknown; function requestIdleCallback( callback: (deadline: { didTimeout: boolean; timeRemaining: () => number; }) => void, options?: {timeout: number}, - ): IdleCallbackID; - function cancelIdleCallback(handle: IdleCallbackID): void; + ): number; + function cancelIdleCallback(handle: number | null | undefined): void; function fetchBundle( bundleId: number,