Hi,
I’m trying to use service binding RPC with Typescript. My learning POC works, but I can’t figure out how to get the service class definition from my Service to the client. In javascript it works without problem in Typescript too, but with errors. (Property ‘ping’ does not exist on type )
Service Worker
import { WorkerEntrypoint } from "cloudflare:workers";
export default class extends WorkerEntrypoint {
async ping() : Promise<Number>{
console.log('Call: ping');
return Date.now()
}
};
Client Worker
Interface Env {
SERVICE_TS_TEST_A: Fetcher;
}
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const value = await env.SERVICE_TS_TEST_A.ping();
return new Response(`${value}`,{status: 200});
}
}
[[services]]
binding = "SERVICE_TS_TEST_A"
service = "service-ts-test-a"
Documentation 2) example snippet:
interface Env {
SUM_SERVICE: Service<SumService>;
}
My question is how do I make this association? In the example, how and where is the SumService type defined ?
Thanks for advices.
Documentation I used:
Service bindings - RPC (WorkerEntrypoint) · Cloudflare Workers docs
Workers RPC — TypeScript · Cloudflare Workers docs
3 Likes
Bumping this, as it has not been replied to for 27 days and the documentation is definitely lacking proper Typescript examples!
I’m running into the same issue as @user20284 . I’ve tried another approach which led to yet another error.
Running wrangler types
automatically generates, and forcibly overwrites the type definition to Fetcher
:
// WorkerA - worker-configuration.d.ts
interface Env {
BATCH_WORKER: Fetcher;
}
I’ve tried manually setting the type as per the documentation and skipping running wrangler types
.
// WorkerA - worker-configuration.d.ts
interface Env {
BATCH_WORKER: Service<BatchWorker>;
}
But now I run into the Typescript error:
Type instantiation is excessively deep and possibly infinite.ts(2589)
Because my bound worker is defined as:
// Worker B - src/index.ts
export default class BatchWorker extends WorkerEntrypoint<Env> {
async doSomeBatchWork() {
const url = this.env.API_URL;
const { results } = await this.env.D1.prepare("...").all();
}
}
// Worker B - worker-configuration.d.ts
interface Env {
API_URL = "https://...";
D1: D1Database;
}
Notice the generic type Env
, which is needed to access environment variables, D1 etc.
Everything in Worker B works as expected.
So, Cloudflare team, please do not neglect updating the documentation with complete TS examples, not just stubs (without any context as seen on RPC > TypeScript )
5 Likes
Looking for help with this as well!
kyliau
July 13, 2024, 11:34pm
4
The following worked for me:
// Service A
export default class ServiceA extends WorkerEntrypoint {
// ...
}
// Service B - worker-configuration.d.ts
import ServiceA from '../service-a/src/index';
interface Env {
SERVICE_A_WORKER: Service<ServiceA>;
}