Skip to content

Commit a2fb747

Browse files
committed
Add TypeScript declarations for the performance global
React Native installs a `performance` global (setUpPerformance) along with the Performance, PerformanceEntry, PerformanceMark and PerformanceMeasure globals, and the Flow libdefs declare it, but src/types/globals.d.ts did not. Projects compiled without lib "dom" got "Cannot find name 'performance'". Declare these globals based on the Flow implementation in src/private/webapis/performance, and add type tests. Fixes #58610
1 parent 024b474 commit a2fb747

2 files changed

Lines changed: 141 additions & 0 deletions

File tree

‎packages/react-native/__typetests__/globals.tsx‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,49 @@ const clonedValue: {nested: {value: number}} = structuredClone({
1515
});
1616
console.log(domExceptionCode, dataCloneErrorCode, clonedValue.nested.value);
1717

18+
function testPerformance() {
19+
const start: number = performance.now();
20+
const timeOrigin: number = performance.timeOrigin;
21+
22+
const mark: PerformanceMark = performance.mark('start', {
23+
detail: {foo: 'bar'},
24+
startTime: start,
25+
});
26+
const markDetail: unknown = mark.detail;
27+
performance.mark('end');
28+
29+
const measure: PerformanceMeasure = performance.measure('duration', 'start', 'end');
30+
const measureDetail: unknown = measure.detail;
31+
performance.measure('withOptions', {start: 'start', end: 'end', detail: 1});
32+
performance.measure('withDuration', {start, duration: 10});
33+
34+
const entries: ReadonlyArray<PerformanceEntry> = performance.getEntries();
35+
const marks: ReadonlyArray<PerformanceEntry> = performance.getEntriesByType('mark');
36+
const named: ReadonlyArray<PerformanceEntry> = performance.getEntriesByName('start', 'mark');
37+
const entry = entries[0];
38+
const name: string = entry.name;
39+
const entryType: PerformanceEntryType = entry.entryType;
40+
const startTime: number = entry.startTime;
41+
const duration: number = entry.duration;
42+
const json: {name: string; entryType: PerformanceEntryType; startTime: number; duration: number} = entry.toJSON();
43+
44+
performance.clearMarks();
45+
performance.clearMarks('start');
46+
performance.clearMeasures();
47+
performance.clearMeasures('duration');
48+
49+
const customMark: PerformanceMark = new PerformanceMark('custom', {startTime: 1});
50+
const isPerformance: boolean = performance instanceof Performance;
51+
52+
console.log(timeOrigin, markDetail, measureDetail, marks, named, name, startTime, duration, json, customMark, isPerformance);
53+
54+
// @ts-expect-error
55+
performance.mark();
56+
57+
// @ts-expect-error
58+
performance.getEntriesByType('wrong-type');
59+
}
60+
1861
function testInterval() {
1962
clearInterval(null);
2063
clearInterval(undefined);

‎packages/react-native/src/types/globals.d.ts‎

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,104 @@ declare global {
120120

121121
function structuredClone<T>(value: T): T;
122122

123+
type PerformanceEntryType =
124+
'mark' | 'measure' | 'event' | 'longtask' | 'resource';
125+
126+
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceEntry) */
127+
interface PerformanceEntry {
128+
readonly name: string;
129+
readonly entryType: PerformanceEntryType;
130+
readonly startTime: number;
131+
readonly duration: number;
132+
toJSON(): {
133+
name: string;
134+
entryType: PerformanceEntryType;
135+
startTime: number;
136+
duration: number;
137+
};
138+
}
139+
140+
var PerformanceEntry: {
141+
prototype: PerformanceEntry;
142+
new (): PerformanceEntry;
143+
};
144+
145+
interface PerformanceMarkOptions {
146+
detail?: unknown;
147+
startTime?: number;
148+
}
149+
150+
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceMark) */
151+
interface PerformanceMark extends PerformanceEntry {
152+
readonly detail: unknown;
153+
}
154+
155+
var PerformanceMark: {
156+
prototype: PerformanceMark;
157+
new (
158+
markName: string,
159+
markOptions?: PerformanceMarkOptions,
160+
): PerformanceMark;
161+
};
162+
163+
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceMeasure) */
164+
interface PerformanceMeasure extends PerformanceEntry {
165+
readonly detail: unknown;
166+
}
167+
168+
var PerformanceMeasure: {
169+
prototype: PerformanceMeasure;
170+
new (): PerformanceMeasure;
171+
};
172+
173+
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance) */
174+
interface Performance {
175+
readonly timeOrigin: number;
176+
now(): number;
177+
mark(
178+
markName: string,
179+
markOptions?: PerformanceMarkOptions,
180+
): PerformanceMark;
181+
clearMarks(markName?: string): void;
182+
measure(
183+
measureName: string,
184+
startMarkOrOptions?:
185+
| string
186+
| {
187+
detail?: unknown;
188+
start?: number | string;
189+
duration?: number;
190+
}
191+
| {
192+
detail?: unknown;
193+
start?: number | string;
194+
end?: number | string;
195+
}
196+
| {
197+
detail?: unknown;
198+
duration?: number | string;
199+
end?: number | string;
200+
},
201+
endMark?: string,
202+
): PerformanceMeasure;
203+
clearMeasures(measureName?: string): void;
204+
getEntries(): ReadonlyArray<PerformanceEntry>;
205+
getEntriesByType(
206+
entryType: PerformanceEntryType,
207+
): ReadonlyArray<PerformanceEntry>;
208+
getEntriesByName(
209+
entryName: string,
210+
entryType?: PerformanceEntryType,
211+
): ReadonlyArray<PerformanceEntry>;
212+
}
213+
214+
var Performance: {
215+
prototype: Performance;
216+
new (): Performance;
217+
};
218+
219+
var performance: Performance;
220+
123221
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly) */
124222
interface DOMRectReadOnly {
125223
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/bottom) */

0 commit comments

Comments
 (0)