diff --git a/CHANGELOG.md b/CHANGELOG.md index eca10d76dbbf..387d85087bba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## v0.85.0-rc.7 +### Added + +- **TypeScript**: Add global type declarations for `TextEncoder` and `TextDecoder` ([#56326](https://github.com/facebook/react-native/pull/56326) by [@deyaaeldeen](https://github.com/deyaaeldeen)) + ### Fixed #### iOS specific diff --git a/packages/react-native/src/types/globals.d.ts b/packages/react-native/src/types/globals.d.ts index 4082da352804..a374d31c8187 100644 --- a/packages/react-native/src/types/globals.d.ts +++ b/packages/react-native/src/types/globals.d.ts @@ -695,5 +695,98 @@ declare global { readonly LOADING: 1; }; + // #endregion + // #region TextEncoder / TextDecoder + // Available natively in Hermes. + // TextEncoder: since React Native 0.74 + // TextDecoder: since React Native 0.85 + + /** + * Result of {@link TextEncoder.encodeInto}. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextEncoder/encodeInto#return_value) + */ + interface TextEncoderEncodeIntoResult { + /** The number of UTF-16 units of code read from the input string. */ + read: number; + /** The number of bytes written to the destination `Uint8Array`. */ + written: number; + } + + /** + * TextEncoder takes a stream of code points as input and emits a stream of + * UTF-8 bytes. Hermes only supports UTF-8 encoding. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextEncoder) + */ + interface TextEncoder { + /** Always `"utf-8"`. [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextEncoder/encoding) */ + readonly encoding: 'utf-8'; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextEncoder/encode) */ + encode(input?: string): Uint8Array; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextEncoder/encodeInto) */ + encodeInto( + input: string, + destination: Uint8Array, + ): TextEncoderEncodeIntoResult; + } + + var TextEncoder: { + prototype: TextEncoder; + new (): TextEncoder; + }; + + /** + * Options for the {@link TextDecoder} constructor. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoder/TextDecoder#options) + */ + interface TextDecoderOptions { + /** If `true`, a `TypeError` is thrown on invalid byte sequences. Defaults to `false`. */ + fatal?: boolean | undefined; + /** If `true`, the byte order mark is included in the output. Defaults to `false`. */ + ignoreBOM?: boolean | undefined; + } + + /** + * Options for {@link TextDecoder.decode}. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoder/decode#options) + */ + interface TextDecodeOptions { + /** + * If `true`, indicates that additional data will follow in subsequent calls + * to `decode()`. Defaults to `false`. + */ + stream?: boolean | undefined; + } + + /** + * TextDecoder takes a stream of bytes as input and emits a stream of code + * points. + * + * Hermes supports the following encodings: + * UTF-8, UTF-16LE, UTF-16BE, and single-byte encodings (ISO-8859-2 through + * ISO-8859-16, Windows-874, Windows-1250 through Windows-1258, KOI8-R, + * KOI8-U, IBM866, Macintosh, x-mac-cyrillic). + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoder) + */ + interface TextDecoder { + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoder/encoding) */ + readonly encoding: string; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoder/fatal) */ + readonly fatal: boolean; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoder/ignoreBOM) */ + readonly ignoreBOM: boolean; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoder/decode) */ + decode(input?: ArrayBufferView | ArrayBuffer, options?: TextDecodeOptions): string; + } + + var TextDecoder: { + prototype: TextDecoder; + new (label?: string, options?: TextDecoderOptions): TextDecoder; + }; + // #endregion } diff --git a/packages/react-native/types/__typetests__/globals.tsx b/packages/react-native/types/__typetests__/globals.tsx index 8bacebf8c5f7..1f2f3a836c27 100644 --- a/packages/react-native/types/__typetests__/globals.tsx +++ b/packages/react-native/types/__typetests__/globals.tsx @@ -216,3 +216,24 @@ const formData = new FormData(); formData.append('file', { fileName: 'example' }); console.log(formData.getParts()); console.log(formData.getAll('username')); + +// TextEncoder +const encoder = new TextEncoder(); +const encoded: Uint8Array = encoder.encode('hello'); +const encodedEmpty: Uint8Array = encoder.encode(); +const encoding: 'utf-8' = encoder.encoding; +const encodeIntoResult: TextEncoderEncodeIntoResult = encoder.encodeInto( + 'hello', + new Uint8Array(10), +); +console.log(encodeIntoResult.read, encodeIntoResult.written); + +// TextDecoder +const decoder = new TextDecoder(); +const decoderUtf8 = new TextDecoder('utf-8'); +const decoderWithOpts = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }); +const decoded: string = decoder.decode(new Uint8Array([104, 105])); +const decodedFromBuffer: string = decoder.decode(new ArrayBuffer(2)); +const decodedEmpty: string = decoder.decode(); +const decodedStream: string = decoder.decode(new Uint8Array([0xe6, 0x97]), { stream: true }); +console.log(decoder.encoding, decoder.fatal, decoder.ignoreBOM);