cloudflare / workerd

The JavaScript / Wasm runtime that powers Cloudflare Workers
https://blog.cloudflare.com/workerd-open-source-workers-runtime/
Apache License 2.0
6.28k stars 304 forks source link

RPC `Response` type not compatible with Worker #3042

Open Ehesp opened 2 weeks ago

Ehesp commented 2 weeks ago

Given the following worker code:

export default {
    async fetch(request, env, ctx): Promise<Response> {
        const id = env.MY_DO.idFromName('foo');
        const stub = env.MY_DO.get(id);
        const foo = await stub.config({});
        const response = await foo.fetch(request);
        return response;
    },
} satisfies ExportedHandler<Env>;

And the following DO:

export class MyDO extends DurableObject {
  config(config: any) {
    this.configuration = config;
    return { fetch: this.fetch.bind(this) };
  }

  fetch(request: Request) {
    const config = this.configuration;
    // Do stuff with config
    return new Response('Foo bar');
  }
}

I get the following TypeScript error:

Type '{ clone: Stub<() => Response>; status: number; statusText: string; headers: { get: Stub<(name: string) => string | null>; getAll: Stub<(name: string) => string[]>; ... 9 more ...; [Symbol.iterator]: Stub<...>; }; ... 12 more ...; blob: Stub<...>; } & Disposable' is not assignable to type 'Response'.
  The types of 'clone(...).status' are incompatible between these types.
    Type 'Promise<number>' is not assignable to type 'number'.ts(2322)

The code actually runs and executes fine as I'd expect. Is this expected to work and there's a TS error, or shouldn't this work and I've not hit some sort of edge case with RPC?

The main concern here is ensuring there's only a single billable request.

JustFly1984 commented 2 weeks ago

I have the same issue. It is and issue with "@cloudflare/workers-types" after "4.20241011.0". If you update to "4.2024102.0", or current 4.20241106.0, it fails with error:

<T>(): Promise<T>; }>; readonly body: { readonly locked: boolean; cancel: Stub<(reason?: any) => Promise<void>>; getReader: Stub<{ (): ReadableStreamDefaultReader<any>; (options: ReadableStreamGetReaderOptions): ReadableStreamBYOBReader; }>; pipeThrough: Stub<(<T>(transform: ReadableWritablePair<T, any>, options?: StreamPipeOptions | undefined) => ReadableStream<T>)>; pipeTo: Stub<(destination: WritableStream<any>, options?: StreamPipeOptions | undefined) => Promise<void>>; tee: Stub<() => [ReadableStream<any>, ReadableStream<any>]>; values: Stub<(options?: ReadableStreamValuesOptions | undefined) => AsyncIterableIterator<any>>; [Symbol.asyncIterator]: Stub<(options?: ReadableStreamValuesOptions | undefined) => AsyncIterableIterator<any>>; } | null; readonly bodyUsed: boolean; arrayBuffer: Stub<() => Promise<ArrayBuffer>>; bytes: Stub<() => Promise<Uint8Array>>; text: Stub<() => Promise<string>>; formData: Stub<() => Promise<FormData>>; blob: Stub<() => Promise<Blob>>; } & Disposable' is not assignable to type 'Response'.
  The types of 'clone(...).status' are incompatible between these types.
    Type 'Promise<number>' is not assignable to type 'number'.ts(2322)

Reverting back to 11 fixes an issue.

jasnell commented 2 weeks ago

@kentonv ... pretty sure this is just a ts type issue but just in case there's something deeper happening here...

JustFly1984 commented 1 week ago

@jasnell @kentonv I've updated @cloudflare/vitest-pool-workers package, and it seems ok, but I've seen warnings that it requires latest types, in pnpm install logs.

JustFly1984 commented 1 week ago

PS, I'm using RPC workers, aswel with hono router, very happy with architecture, Thanks everyone who maintains workers and community!

JustFly1984 commented 1 week ago

@jasnell @kentonv I've tested the latest release of @cloudflare/workers-types and it still have same issue. reverted back to 4.20241011.0

kentonv commented 1 week ago

This looks like some sort of bug with the magic TypeScript that generates RPC stub types. @penalosa any idea what the issue is here?