From 4330ef553f6fb5c478916947654859853221a9b3 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Wed, 27 Nov 2024 04:42:54 +0900 Subject: [PATCH] fix(streams): reject `string` in `ReadableStream.from` type (#25116) WebIDL `async iterable` type rejects `string` Ref https://github.com/whatwg/webidl/pull/1397, #24623 --- cli/tsc/dts/lib.dom.d.ts | 2 +- ext/web/06_streams.js | 4 ++-- ext/web/06_streams_types.d.ts | 4 ++-- ext/web/lib.deno_web.d.ts | 2 +- .../reject_string_in_readable_stream_from/__test__.jsonc | 5 +++++ .../check/reject_string_in_readable_stream_from/main.out | 5 +++++ .../check/reject_string_in_readable_stream_from/main.ts | 1 + tests/unit/streams_test.ts | 1 + 8 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 tests/specs/check/reject_string_in_readable_stream_from/__test__.jsonc create mode 100644 tests/specs/check/reject_string_in_readable_stream_from/main.out create mode 100644 tests/specs/check/reject_string_in_readable_stream_from/main.ts diff --git a/cli/tsc/dts/lib.dom.d.ts b/cli/tsc/dts/lib.dom.d.ts index 0a2f9b9eda..2684735597 100644 --- a/cli/tsc/dts/lib.dom.d.ts +++ b/cli/tsc/dts/lib.dom.d.ts @@ -18277,7 +18277,7 @@ declare var ReadableStream: { new(underlyingSource: UnderlyingByteSource, strategy?: { highWaterMark?: number }): ReadableStream; new(underlyingSource: UnderlyingDefaultSource, strategy?: QueuingStrategy): ReadableStream; new(underlyingSource?: UnderlyingSource, strategy?: QueuingStrategy): ReadableStream; - from(asyncIterable: AsyncIterable | Iterable>): ReadableStream; + from(asyncIterable: AsyncIterable | Iterable> & object): ReadableStream; }; /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBReader) */ diff --git a/ext/web/06_streams.js b/ext/web/06_streams.js index f29e5f2040..57a437e4f5 100644 --- a/ext/web/06_streams.js +++ b/ext/web/06_streams.js @@ -2922,7 +2922,7 @@ function readableStreamPipeTo( } /** - * @param {ReadableStreamGenericReader | ReadableStreamBYOBReader} reader + * @param {ReadableStreamGenericReader | ReadableStreamBYOBReader} reader * @param {any} reason * @returns {Promise} */ @@ -2955,7 +2955,7 @@ function readableStreamReaderGenericInitialize(reader, stream) { /** * @template R - * @param {ReadableStreamGenericReader | ReadableStreamBYOBReader} reader + * @param {ReadableStreamGenericReader | ReadableStreamBYOBReader} reader */ function readableStreamReaderGenericRelease(reader) { const stream = reader[_stream]; diff --git a/ext/web/06_streams_types.d.ts b/ext/web/06_streams_types.d.ts index e04f568d26..fe05ee6e65 100644 --- a/ext/web/06_streams_types.d.ts +++ b/ext/web/06_streams_types.d.ts @@ -60,8 +60,8 @@ interface VoidFunction { (): void; } -interface ReadableStreamGenericReader { - readonly closed: Promise; +interface ReadableStreamGenericReader { + readonly closed: Promise; // deno-lint-ignore no-explicit-any cancel(reason?: any): Promise; } diff --git a/ext/web/lib.deno_web.d.ts b/ext/web/lib.deno_web.d.ts index 2ad97ac7d1..8aafbad535 100644 --- a/ext/web/lib.deno_web.d.ts +++ b/ext/web/lib.deno_web.d.ts @@ -882,7 +882,7 @@ declare var ReadableStream: { strategy?: QueuingStrategy, ): ReadableStream; from( - asyncIterable: AsyncIterable | Iterable>, + asyncIterable: AsyncIterable | Iterable> & object, ): ReadableStream; }; diff --git a/tests/specs/check/reject_string_in_readable_stream_from/__test__.jsonc b/tests/specs/check/reject_string_in_readable_stream_from/__test__.jsonc new file mode 100644 index 0000000000..634dbac850 --- /dev/null +++ b/tests/specs/check/reject_string_in_readable_stream_from/__test__.jsonc @@ -0,0 +1,5 @@ +{ + "args": "check ./main.ts", + "output": "main.out", + "exitCode": 1 +} diff --git a/tests/specs/check/reject_string_in_readable_stream_from/main.out b/tests/specs/check/reject_string_in_readable_stream_from/main.out new file mode 100644 index 0000000000..577c1fb059 --- /dev/null +++ b/tests/specs/check/reject_string_in_readable_stream_from/main.out @@ -0,0 +1,5 @@ +Check [WILDCARD]/main.ts +error: TS2345 [ERROR]: Argument of type 'string' is not assignable to parameter of type 'AsyncIterable | (Iterable> & object)'. +ReadableStream.from("string"); + ~~~~~~~~ + at [WILDCARD]/main.ts:1:21 diff --git a/tests/specs/check/reject_string_in_readable_stream_from/main.ts b/tests/specs/check/reject_string_in_readable_stream_from/main.ts new file mode 100644 index 0000000000..5e7fc9c956 --- /dev/null +++ b/tests/specs/check/reject_string_in_readable_stream_from/main.ts @@ -0,0 +1 @@ +ReadableStream.from("string"); diff --git a/tests/unit/streams_test.ts b/tests/unit/streams_test.ts index 73f9a60953..53225a1553 100644 --- a/tests/unit/streams_test.ts +++ b/tests/unit/streams_test.ts @@ -541,6 +541,7 @@ Deno.test(async function decompressionStreamInvalidGzipStillReported() { Deno.test(function readableStreamFromWithStringThrows() { assertThrows( + // @ts-expect-error: primitives are not acceptable () => ReadableStream.from("string"), TypeError, "Failed to execute 'ReadableStream.from': Argument 1 can not be converted to async iterable.",