From e3c3dac936b23b1db78f7f85374c283326320a95 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 19 Sep 2026 01:51:30 +0000 Subject: [PATCH 1/3] Initial plan From 2340f3c6b3b09f526b9df8b48031ea6996cc5b0f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 19 Sep 2026 01:55:44 +0000 Subject: [PATCH 2/3] Add compiler test showing WritableStream chunk bivariance Co-authored-by: RyanCavanaugh <6685088+RyanCavanaugh@users.noreply.github.com> --- .../compiler/writableStreamChunkVariance.js | 21 +++++++ .../writableStreamChunkVariance.symbols | 49 +++++++++++++++ .../writableStreamChunkVariance.types | 59 +++++++++++++++++++ .../compiler/writableStreamChunkVariance.ts | 12 ++++ 4 files changed, 141 insertions(+) create mode 100644 tsc/testdata/baselines/reference/compiler/writableStreamChunkVariance.js create mode 100644 tsc/testdata/baselines/reference/compiler/writableStreamChunkVariance.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/writableStreamChunkVariance.types create mode 100644 tsc/testdata/tests/cases/compiler/writableStreamChunkVariance.ts diff --git a/tsc/testdata/baselines/reference/compiler/writableStreamChunkVariance.js b/tsc/testdata/baselines/reference/compiler/writableStreamChunkVariance.js new file mode 100644 index 0000000000000..b399eac2ec05c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/writableStreamChunkVariance.js @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/writableStreamChunkVariance.ts] //// + +//// [writableStreamChunkVariance.ts] +const stream: WritableStream<{ a: string }> = new WritableStream<{ a: string; b: string }>(); +stream.getWriter().write({ a: "string" }); + +const writable = new WritableStream<{ a: string; b: string }>(); +new ReadableStream<{ a: string }>().pipeTo(writable); + +const widened: WritableStream<{ a: string; b: string }> = new WritableStream<{ a: string }>(); +new ReadableStream<{ a: string; b: string }>().pipeTo(new WritableStream<{ a: string }>()); + + +//// [writableStreamChunkVariance.js] +"use strict"; +const stream = new WritableStream(); +stream.getWriter().write({ a: "string" }); +const writable = new WritableStream(); +new ReadableStream().pipeTo(writable); +const widened = new WritableStream(); +new ReadableStream().pipeTo(new WritableStream()); diff --git a/tsc/testdata/baselines/reference/compiler/writableStreamChunkVariance.symbols b/tsc/testdata/baselines/reference/compiler/writableStreamChunkVariance.symbols new file mode 100644 index 0000000000000..8f7ac435bef31 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/writableStreamChunkVariance.symbols @@ -0,0 +1,49 @@ +//// [tests/cases/compiler/writableStreamChunkVariance.ts] //// + +=== writableStreamChunkVariance.ts === +const stream: WritableStream<{ a: string }> = new WritableStream<{ a: string; b: string }>(); +>stream : Symbol(stream, Decl(writableStreamChunkVariance.ts, 0, 5)) +>WritableStream : Symbol(WritableStream, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>a : Symbol(a, Decl(writableStreamChunkVariance.ts, 0, 30)) +>WritableStream : Symbol(WritableStream, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>a : Symbol(a, Decl(writableStreamChunkVariance.ts, 0, 66)) +>b : Symbol(b, Decl(writableStreamChunkVariance.ts, 0, 77)) + +stream.getWriter().write({ a: "string" }); +>stream.getWriter().write : Symbol(WritableStreamDefaultWriter.write, Decl(lib.dom.d.ts, --, --)) +>stream.getWriter : Symbol(WritableStream.getWriter, Decl(lib.dom.d.ts, --, --)) +>stream : Symbol(stream, Decl(writableStreamChunkVariance.ts, 0, 5)) +>getWriter : Symbol(WritableStream.getWriter, Decl(lib.dom.d.ts, --, --)) +>write : Symbol(WritableStreamDefaultWriter.write, Decl(lib.dom.d.ts, --, --)) +>a : Symbol(a, Decl(writableStreamChunkVariance.ts, 1, 26)) + +const writable = new WritableStream<{ a: string; b: string }>(); +>writable : Symbol(writable, Decl(writableStreamChunkVariance.ts, 3, 5)) +>WritableStream : Symbol(WritableStream, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>a : Symbol(a, Decl(writableStreamChunkVariance.ts, 3, 37)) +>b : Symbol(b, Decl(writableStreamChunkVariance.ts, 3, 48)) + +new ReadableStream<{ a: string }>().pipeTo(writable); +>new ReadableStream<{ a: string }>().pipeTo : Symbol(ReadableStream.pipeTo, Decl(lib.dom.d.ts, --, --)) +>ReadableStream : Symbol(ReadableStream, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>a : Symbol(a, Decl(writableStreamChunkVariance.ts, 4, 20)) +>pipeTo : Symbol(ReadableStream.pipeTo, Decl(lib.dom.d.ts, --, --)) +>writable : Symbol(writable, Decl(writableStreamChunkVariance.ts, 3, 5)) + +const widened: WritableStream<{ a: string; b: string }> = new WritableStream<{ a: string }>(); +>widened : Symbol(widened, Decl(writableStreamChunkVariance.ts, 6, 5)) +>WritableStream : Symbol(WritableStream, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>a : Symbol(a, Decl(writableStreamChunkVariance.ts, 6, 31)) +>b : Symbol(b, Decl(writableStreamChunkVariance.ts, 6, 42)) +>WritableStream : Symbol(WritableStream, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>a : Symbol(a, Decl(writableStreamChunkVariance.ts, 6, 78)) + +new ReadableStream<{ a: string; b: string }>().pipeTo(new WritableStream<{ a: string }>()); +>new ReadableStream<{ a: string; b: string }>().pipeTo : Symbol(ReadableStream.pipeTo, Decl(lib.dom.d.ts, --, --)) +>ReadableStream : Symbol(ReadableStream, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>a : Symbol(a, Decl(writableStreamChunkVariance.ts, 7, 20)) +>b : Symbol(b, Decl(writableStreamChunkVariance.ts, 7, 31)) +>pipeTo : Symbol(ReadableStream.pipeTo, Decl(lib.dom.d.ts, --, --)) +>WritableStream : Symbol(WritableStream, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>a : Symbol(a, Decl(writableStreamChunkVariance.ts, 7, 74)) + diff --git a/tsc/testdata/baselines/reference/compiler/writableStreamChunkVariance.types b/tsc/testdata/baselines/reference/compiler/writableStreamChunkVariance.types new file mode 100644 index 0000000000000..d38c66b68a3c4 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/writableStreamChunkVariance.types @@ -0,0 +1,59 @@ +//// [tests/cases/compiler/writableStreamChunkVariance.ts] //// + +=== writableStreamChunkVariance.ts === +const stream: WritableStream<{ a: string }> = new WritableStream<{ a: string; b: string }>(); +>stream : WritableStream<{ a: string; }> +>a : string +>new WritableStream<{ a: string; b: string }>() : WritableStream<{ a: string; b: string; }> +>WritableStream : { new (underlyingSink?: UnderlyingSink, strategy?: QueuingStrategy): WritableStream; prototype: WritableStream; } +>a : string +>b : string + +stream.getWriter().write({ a: "string" }); +>stream.getWriter().write({ a: "string" }) : Promise +>stream.getWriter().write : (chunk?: { a: string; } | undefined) => Promise +>stream.getWriter() : WritableStreamDefaultWriter<{ a: string; }> +>stream.getWriter : () => WritableStreamDefaultWriter<{ a: string; }> +>stream : WritableStream<{ a: string; }> +>getWriter : () => WritableStreamDefaultWriter<{ a: string; }> +>write : (chunk?: { a: string; } | undefined) => Promise +>{ a: "string" } : { a: string; } +>a : string +>"string" : "string" + +const writable = new WritableStream<{ a: string; b: string }>(); +>writable : WritableStream<{ a: string; b: string; }> +>new WritableStream<{ a: string; b: string }>() : WritableStream<{ a: string; b: string; }> +>WritableStream : { new (underlyingSink?: UnderlyingSink, strategy?: QueuingStrategy): WritableStream; prototype: WritableStream; } +>a : string +>b : string + +new ReadableStream<{ a: string }>().pipeTo(writable); +>new ReadableStream<{ a: string }>().pipeTo(writable) : Promise +>new ReadableStream<{ a: string }>().pipeTo : (destination: WritableStream<{ a: string; }>, options?: StreamPipeOptions) => Promise +>new ReadableStream<{ a: string }>() : ReadableStream<{ a: string; }> +>ReadableStream : { new (underlyingSource: UnderlyingByteSource, strategy?: { highWaterMark?: number; }): ReadableStream>; new (underlyingSource: UnderlyingDefaultSource, strategy?: QueuingStrategy): ReadableStream; new (underlyingSource?: UnderlyingSource, strategy?: QueuingStrategy): ReadableStream; prototype: ReadableStream; } +>a : string +>pipeTo : (destination: WritableStream<{ a: string; }>, options?: StreamPipeOptions) => Promise +>writable : WritableStream<{ a: string; b: string; }> + +const widened: WritableStream<{ a: string; b: string }> = new WritableStream<{ a: string }>(); +>widened : WritableStream<{ a: string; b: string; }> +>a : string +>b : string +>new WritableStream<{ a: string }>() : WritableStream<{ a: string; }> +>WritableStream : { new (underlyingSink?: UnderlyingSink, strategy?: QueuingStrategy): WritableStream; prototype: WritableStream; } +>a : string + +new ReadableStream<{ a: string; b: string }>().pipeTo(new WritableStream<{ a: string }>()); +>new ReadableStream<{ a: string; b: string }>().pipeTo(new WritableStream<{ a: string }>()) : Promise +>new ReadableStream<{ a: string; b: string }>().pipeTo : (destination: WritableStream<{ a: string; b: string; }>, options?: StreamPipeOptions) => Promise +>new ReadableStream<{ a: string; b: string }>() : ReadableStream<{ a: string; b: string; }> +>ReadableStream : { new (underlyingSource: UnderlyingByteSource, strategy?: { highWaterMark?: number; }): ReadableStream>; new (underlyingSource: UnderlyingDefaultSource, strategy?: QueuingStrategy): ReadableStream; new (underlyingSource?: UnderlyingSource, strategy?: QueuingStrategy): ReadableStream; prototype: ReadableStream; } +>a : string +>b : string +>pipeTo : (destination: WritableStream<{ a: string; b: string; }>, options?: StreamPipeOptions) => Promise +>new WritableStream<{ a: string }>() : WritableStream<{ a: string; }> +>WritableStream : { new (underlyingSink?: UnderlyingSink, strategy?: QueuingStrategy): WritableStream; prototype: WritableStream; } +>a : string + diff --git a/tsc/testdata/tests/cases/compiler/writableStreamChunkVariance.ts b/tsc/testdata/tests/cases/compiler/writableStreamChunkVariance.ts new file mode 100644 index 0000000000000..6abc99c505f48 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/writableStreamChunkVariance.ts @@ -0,0 +1,12 @@ +// @strict: true +// @target: esnext +// @lib: esnext,dom + +const stream: WritableStream<{ a: string }> = new WritableStream<{ a: string; b: string }>(); +stream.getWriter().write({ a: "string" }); + +const writable = new WritableStream<{ a: string; b: string }>(); +new ReadableStream<{ a: string }>().pipeTo(writable); + +const widened: WritableStream<{ a: string; b: string }> = new WritableStream<{ a: string }>(); +new ReadableStream<{ a: string; b: string }>().pipeTo(new WritableStream<{ a: string }>()); From 9ea6f08f9d885cb3dd1ef5065634d11bb85fcb88 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 19 Sep 2026 02:08:05 +0000 Subject: [PATCH 3/3] Make WritableStreamDefaultWriter.write a function property Co-authored-by: RyanCavanaugh <6685088+RyanCavanaugh@users.noreply.github.com> --- tsc/internal/bundled/libs/lib.dom.d.ts | 2 +- tsc/internal/bundled/libs/lib.webworker.d.ts | 2 +- .../writableStreamChunkVariance.errors.txt | 24 +++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 tsc/testdata/baselines/reference/compiler/writableStreamChunkVariance.errors.txt diff --git a/tsc/internal/bundled/libs/lib.dom.d.ts b/tsc/internal/bundled/libs/lib.dom.d.ts index 9e127c3f5a524..f9b914c4451cd 100644 --- a/tsc/internal/bundled/libs/lib.dom.d.ts +++ b/tsc/internal/bundled/libs/lib.dom.d.ts @@ -41916,7 +41916,7 @@ interface WritableStreamDefaultWriter { * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultWriter/write) */ - write(chunk?: W): Promise; + write: (chunk?: W) => Promise; } declare var WritableStreamDefaultWriter: { diff --git a/tsc/internal/bundled/libs/lib.webworker.d.ts b/tsc/internal/bundled/libs/lib.webworker.d.ts index 45c6a6134821d..e8e07ef6a19a5 100644 --- a/tsc/internal/bundled/libs/lib.webworker.d.ts +++ b/tsc/internal/bundled/libs/lib.webworker.d.ts @@ -14159,7 +14159,7 @@ interface WritableStreamDefaultWriter { * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultWriter/write) */ - write(chunk?: W): Promise; + write: (chunk?: W) => Promise; } declare var WritableStreamDefaultWriter: { diff --git a/tsc/testdata/baselines/reference/compiler/writableStreamChunkVariance.errors.txt b/tsc/testdata/baselines/reference/compiler/writableStreamChunkVariance.errors.txt new file mode 100644 index 0000000000000..dc71161801322 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/writableStreamChunkVariance.errors.txt @@ -0,0 +1,24 @@ +writableStreamChunkVariance.ts(1,7): error TS2322: Type 'WritableStream<{ a: string; b: string; }>' is not assignable to type 'WritableStream<{ a: string; }>'. + Property 'b' is missing in type '{ a: string; }' but required in type '{ a: string; b: string; }'. +writableStreamChunkVariance.ts(5,44): error TS2345: Argument of type 'WritableStream<{ a: string; b: string; }>' is not assignable to parameter of type 'WritableStream<{ a: string; }>'. + Property 'b' is missing in type '{ a: string; }' but required in type '{ a: string; b: string; }'. + + +==== writableStreamChunkVariance.ts (2 errors) ==== + const stream: WritableStream<{ a: string }> = new WritableStream<{ a: string; b: string }>(); + ~~~~~~ +!!! error TS2322: Type 'WritableStream<{ a: string; b: string; }>' is not assignable to type 'WritableStream<{ a: string; }>'. +!!! error TS2322: Property 'b' is missing in type '{ a: string; }' but required in type '{ a: string; b: string; }'. +!!! related TS2728 writableStreamChunkVariance.ts:1:79: 'b' is declared here. + stream.getWriter().write({ a: "string" }); + + const writable = new WritableStream<{ a: string; b: string }>(); + new ReadableStream<{ a: string }>().pipeTo(writable); + ~~~~~~~~ +!!! error TS2345: Argument of type 'WritableStream<{ a: string; b: string; }>' is not assignable to parameter of type 'WritableStream<{ a: string; }>'. +!!! error TS2345: Property 'b' is missing in type '{ a: string; }' but required in type '{ a: string; b: string; }'. +!!! related TS2728 writableStreamChunkVariance.ts:4:50: 'b' is declared here. + + const widened: WritableStream<{ a: string; b: string }> = new WritableStream<{ a: string }>(); + new ReadableStream<{ a: string; b: string }>().pipeTo(new WritableStream<{ a: string }>()); + \ No newline at end of file