Skip to content

Commit 8a7ec50

Browse files
committed
Add TypeScript types for TextEncoder and TextDecoder globals
Both TextEncoder (Hermes 0.74) and TextDecoder (Hermes 0.85) are available at runtime but missing from the TypeScript globals, forcing users to cast through any, pull in lib.dom, or write their own declarations. Adds declarations matching the Hermes implementation and expands the globals typetests to cover the new APIs. Fixes #56325
1 parent 24b51db commit 8a7ec50

2 files changed

Lines changed: 72 additions & 0 deletions

File tree

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

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,59 @@ declare global {
521521
): URLSearchParams;
522522
};
523523

524+
interface TextEncoderEncodeIntoResult {
525+
read: number;
526+
written: number;
527+
}
528+
529+
/**
530+
* Encodes strings to bytes using UTF-8.
531+
* Available in Hermes since React Native 0.74.
532+
*
533+
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextEncoder)
534+
*/
535+
interface TextEncoder {
536+
/** Always `"utf-8"`. */
537+
readonly encoding: string;
538+
encode(input?: string): Uint8Array;
539+
encodeInto(
540+
source: string,
541+
destination: Uint8Array,
542+
): TextEncoderEncodeIntoResult;
543+
}
544+
545+
var TextEncoder: {
546+
prototype: TextEncoder;
547+
new (): TextEncoder;
548+
};
549+
550+
interface TextDecoderOptions {
551+
fatal?: boolean;
552+
ignoreBOM?: boolean;
553+
}
554+
555+
interface TextDecodeOptions {
556+
stream?: boolean;
557+
}
558+
559+
/**
560+
* Decodes bytes to strings. Supports UTF-8 and several legacy encodings.
561+
* Available in Hermes since React Native 0.85.
562+
*
563+
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoder)
564+
*/
565+
interface TextDecoder {
566+
readonly encoding: string;
567+
readonly fatal: boolean;
568+
readonly ignoreBOM: boolean;
569+
decode(input?: BufferSource, options?: TextDecodeOptions): string;
570+
}
571+
572+
var TextDecoder: {
573+
prototype: TextDecoder;
574+
new (label?: string, options?: TextDecoderOptions): TextDecoder;
575+
};
576+
524577
interface WebSocketMessageEvent extends Event {
525578
data?: any | undefined;
526579
}

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,3 +216,22 @@ const formData = new FormData();
216216
formData.append('file', { fileName: 'example' });
217217
console.log(formData.getParts());
218218
console.log(formData.getAll('username'));
219+
220+
const textEncoder = new TextEncoder();
221+
const encodingValue: string = textEncoder.encoding;
222+
const encoded: Uint8Array = textEncoder.encode();
223+
const encoded2: Uint8Array = textEncoder.encode('hello');
224+
const encodeIntoResult = textEncoder.encodeInto('hello', new Uint8Array(10));
225+
const readCount: number = encodeIntoResult.read;
226+
const writtenCount: number = encodeIntoResult.written;
227+
228+
const textDecoder = new TextDecoder();
229+
const textDecoderWithLabel = new TextDecoder('utf-8');
230+
const textDecoderWithOptions = new TextDecoder('utf-8', { fatal: true, ignoreBOM: false });
231+
const decoderEncoding: string = textDecoder.encoding;
232+
const decoderFatal: boolean = textDecoder.fatal;
233+
const decoderIgnoreBOM: boolean = textDecoder.ignoreBOM;
234+
const decoded: string = textDecoder.decode();
235+
const decoded2: string = textDecoder.decode(new Uint8Array([72, 101, 108, 108, 111]));
236+
const decoded3: string = textDecoder.decode(new Uint8Array([72, 101, 108, 108, 111]), { stream: true });
237+
const decoded4: string = textDecoder.decode(new ArrayBuffer(5));

0 commit comments

Comments
 (0)