@cloudflare/worker-types ReadableStream incompatible with TypeScript default

I'm trying to use the body property of a Response object, but it seems like the type declarations in @cloudflare/worker-types conflict with those in @types/node for ReadableStream. I'm a bit stumped as to why TypeScript is looking for types from @types/node. Anyone else run into this issue before? Here's some simple code to reproduce the issue with the default TypeScript starter:
const res = await fetch('https://www.example.com');

if (!res.body) {
throw new Error('No body on request');
}

let body: ReadableStream = res.body;
const res = await fetch('https://www.example.com');

if (!res.body) {
throw new Error('No body on request');
}

let body: ReadableStream = res.body;
which produces the error:
error TS2345: Argument of type 'import("stream/web").ReadableStream<any>' is not assignable to parameter of type 'ReadableStream<any>'.
The types returned by 'getReader(...)' are incompatible between these types.
Property 'readAtLeast' is missing in type 'ReadableStreamDefaultReader<any>' but required in type 'ReadableStreamBYOBReader'.

24 readableStreamConsumer(res.body);
~~~~~~~~

node_modules/.pnpm/@[email protected]/node_modules/@cloudflare/workers-types/experimental/index.d.ts:2019:3
2019 readAtLeast<T extends ArrayBufferView>(
~~~~~~~~~~~
'readAtLeast' is declared here.
error TS2345: Argument of type 'import("stream/web").ReadableStream<any>' is not assignable to parameter of type 'ReadableStream<any>'.
The types returned by 'getReader(...)' are incompatible between these types.
Property 'readAtLeast' is missing in type 'ReadableStreamDefaultReader<any>' but required in type 'ReadableStreamBYOBReader'.

24 readableStreamConsumer(res.body);
~~~~~~~~

node_modules/.pnpm/@[email protected]/node_modules/@cloudflare/workers-types/experimental/index.d.ts:2019:3
2019 readAtLeast<T extends ArrayBufferView>(
~~~~~~~~~~~
'readAtLeast' is declared here.
Not sure what's going on because my tsconfig should ensure TypeScript is only reading from the worker types package:
{
"compilerOptions": {
// ...
"types": ["@cloudflare/workers-types/experimental"]
},
// ...
}
{
"compilerOptions": {
// ...
"types": ["@cloudflare/workers-types/experimental"]
},
// ...
}
I can do res.body as ReadableStream and it's resolved to the ReadableStream from the worker types, so I think the problem is that the type of fetch is being pulled from @types/node for some reason (I can see that overload if I go to definition in VSCode)
6 Replies
pronoun
pronounOP6mo ago
For future reference if anyone else ran into the same issue, it seems like it was because of my vitest.config.ts — in particular this import (included in the starter template) apparently introduced an additional global type declaration for fetch():
import { defineWorkersConfig } from '@cloudflare/vitest-pool-workers/config';
import { defineWorkersConfig } from '@cloudflare/vitest-pool-workers/config';
so I was able to solve the issue with a separate tsconfig for files being run in Node (like my Vitest config)
Jürgen Leschner
Hi @pronoun - thanks for posting this - I have filed an issue here https://github.com/cloudflare/workers-sdk/issues/6211
GitHub
TypeScript errors for ReadableStream in C3 "Hello World" worker ·...
Which Cloudflare product(s) does this pertain to? Impacts C3 "Hello World" TypeScript users - suspected bug in Workers Vitest Integration What version(s) of the tool(s) are you using? @cl...
pronoun
pronounOP5mo ago
Oh I should’ve done that — thanks!
Jürgen Leschner
so I was able to solve the issue with a separate tsconfig for files being run in Node (like my Vitest config)
@pronoun would you mind sharing how you configured a separate tsconfig for vitest (or link to the repo if it's public) 🙏
pronoun
pronounOP5mo ago
huh, I just checked and apparently my setup doesn't do it properly 😅 but I just set tsconfig.json to only include files in my src/ directory and had a separate tsconfig.node.json including only config files running in node it seems like vscode doesn't detect this (the DOM declarations are available) but for me running tsc -p tsconfig.node.json is good enough and I still get intellisense for the config so I guess I didn't notice
Jürgen Leschner
thanks for clarifying that @pronoun - super helpful.
Want results from more Discord servers?
Add your server