Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions packages/react-native/ReactCommon/react/runtime/TimerManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,11 @@ TimerHandle TimerManager::createRecurringTimer(

void TimerManager::deleteTimer(jsi::Runtime& runtime, TimerHandle timerHandle) {
if (timerHandle < 0) {
throw jsi::JSError(runtime, "clearTimeout called with an invalid handle");
// Do nothing for invalid handles (match web spec behavior)
// Links:
// - cancelAnimationFrame: https://www.w3.org/TR/animation-timing/;
// - clearTimeout: https://developer.mozilla.org/en-US/docs/Web/API/Window/clearTimeout#notes)
return;
}

platformTimerRegistry_->deleteTimer(timerHandle);
Expand All @@ -145,7 +149,10 @@ void TimerManager::deleteRecurringTimer(
jsi::Runtime& runtime,
TimerHandle timerHandle) {
if (timerHandle < 0) {
throw jsi::JSError(runtime, "clearInterval called with an invalid handle");
// Do nothing for invalid handles (match web spec behavior)
// Links:
// - clearInterval: https://developer.mozilla.org/en-US/docs/Web/API/Window/clearInterval
return;
}

platformTimerRegistry_->deleteTimer(timerHandle);
Expand Down
8 changes: 4 additions & 4 deletions packages/react-native/src/types/globals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ declare global {

// #region Timer Functions

function clearInterval(handle: number): void;
function clearTimeout(handle: number): void;
function clearInterval(handle: number | null | undefined): void;
function clearTimeout(handle: number | null | undefined): void;
function setInterval(handler: () => void, timeout: number): number;
function setInterval<Args extends any[]>(
handler: (...args: Args) => void,
Expand All @@ -115,14 +115,14 @@ declare global {
timeout?: number,
...args: Args
): number;
function clearImmediate(handle: number): void;
function clearImmediate(handle: number | null | undefined): void;
function setImmediate(handler: () => void): number;
function setImmediate<Args extends any[]>(
handler: (...args: Args) => void,
...args: Args
): number;

function cancelAnimationFrame(handle: number): void;
function cancelAnimationFrame(handle: number | null | undefined): void;
function requestAnimationFrame(callback: (time: number) => void): number;

function fetchBundle(
Expand Down
40 changes: 40 additions & 0 deletions packages/react-native/types/__typetests__/globals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
const noop = () => { };

function testInterval() {
clearInterval(null);
clearInterval(undefined);

let handle = setInterval(noop, 0);
clearInterval(handle);

Expand Down Expand Up @@ -38,6 +41,9 @@ function testInterval() {
}

function testTimeout() {
clearTimeout(null);
clearTimeout(undefined);

let handle = setTimeout(noop, 0);
clearTimeout(handle);

Expand Down Expand Up @@ -68,6 +74,9 @@ function testTimeout() {
}

function testImmediate() {
clearImmediate(null);
clearImmediate(undefined);

let handle = setImmediate(noop);
clearImmediate(handle);

Expand Down Expand Up @@ -97,6 +106,37 @@ function testImmediate() {
clearImmediate(handle);
}

function testRequestAnimationFrame(){
cancelAnimationFrame(null);
cancelAnimationFrame(undefined);

let handle = requestAnimationFrame((time: number) => {
console.log('time', time);
});
cancelAnimationFrame(handle);

handle = requestAnimationFrame(() => {
console.log('no time');
});
cancelAnimationFrame(handle);

handle = requestAnimationFrame(
// @ts-expect-error
(notTime: string) => {
console.log('argument have to be number', notTime);
});
cancelAnimationFrame(handle);

// @ts-expect-error
const resultHaveToBeNum: string = requestAnimationFrame(() => {
console.log('result have to be number');
});
cancelAnimationFrame(
// @ts-expect-error
resultHaveToBeNum
);
}

const fetchCopy: WindowOrWorkerGlobalScope['fetch'] = fetch;

const myHeaders = new Headers();
Expand Down
Loading