Correct TypeScript from WorkerEntrypoint Binding

If I have this service below
export default class Users extends WorkerEntrypoint<Env> {
async fetch() {
return new Response(null, { status: 404 });
}

async list() {
const adapter = new PrismaD1(this.env.DB);
const prisma = new PrismaClient({ adapter });

try {
const users = await prisma.user.findMany();
const result = JSON.stringify(users);
return new Response(result);
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
return Response.json({ e }, { status: 400 });
}
return Response.json({ e }, { status: 500 });
}
}
export default class Users extends WorkerEntrypoint<Env> {
async fetch() {
return new Response(null, { status: 404 });
}

async list() {
const adapter = new PrismaD1(this.env.DB);
const prisma = new PrismaClient({ adapter });

try {
const users = await prisma.user.findMany();
const result = JSON.stringify(users);
return new Response(result);
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
return Response.json({ e }, { status: 400 });
}
return Response.json({ e }, { status: 500 });
}
}
wrangler.toml
name = "users"
main = "src/index.ts"
compatibility_date = "2025-01-09"
wrangler.toml
name = "users"
main = "src/index.ts"
compatibility_date = "2025-01-09"
When I consume this into another service provider it has in its toml
wrangler.toml
[[services]]
binding = "USERS"
service = "users"
entrypoint = "Users"
wrangler.toml
[[services]]
binding = "USERS"
service = "users"
entrypoint = "Users"
When I run wrangler types it generaties this type decleration file
// Generated by Wrangler by running `wrangler types`

interface Env {
USERS: Fetcher;
}
// Generated by Wrangler by running `wrangler types`

interface Env {
USERS: Fetcher;
}
However when I try to use this service it only shows two methods which are the reserved types connect and fetch
No description
9 Replies
DaniFoldi
DaniFoldi•2mo ago
There's a separate type for RPC services, Service<Users> in this case, if you import type Users from './other.ts' The way I usually have them would be USERS: Service<import('other-service').default> as inline type imports
Alex Patterson
Alex PattersonOP•2mo ago
Oh intersting thanks @DaniFoldi ! Maybe this deserves its own question, but it is something I am struggling with when getting started to write out my next course on creating cloudflare workers. I am wondering if it makes sense to continue with multiple wrangler directories for each service like in flipfeeds currently or do something like @Craig has in punderful-workflows creating multiple services in a single wrangler directory. I feel like this is where they typing might also break down because technically they are not even in the same project making imports more difficult
No description
No description
DaniFoldi
DaniFoldi•2mo ago
I would do it in a very similar way to your setup - pnpm monorepo, each worker is a package - make the exported worker's type an export of the package - import them from workspace:^ in other packages - and this should work in the same repo as well as others, if you publish it to a (maybe private) registry
Alex Patterson
Alex PattersonOP•2mo ago
How do you test things like this locally, I am finding it difficult to run workers concurrently with only my gateway being served at 8787. I "hardcoded" port into its pnpm dev command but maybe there is another way?
DaniFoldi
DaniFoldi•2mo ago
I believe the port config option in wrangler.toml/json is what you're looking for, I'd assign them something unique each (insert obligatory testing in production joke) and then an actual explanation, you can use gradual deployments, eg. upload your new version and deploy it to 0% of traffic, which you can override with a header for your own requests
Daniel Klein
Daniel Klein•4w ago
Sorry for interrupting this thread with my own question but im running into same issue and I'm unable to fix it. Could you explain me a bit further how do I accomplish the type of RPC service to be Service<...> instead of type Fetcher when worker-configuration.d.ts is generated ? Thanks a lot
DaniFoldi
DaniFoldi•4w ago
Hey, unfortunately the only solution I can give is to manually overwrite it :/ sadly generics are not supported by the type generator right now, even though it would be super useful, and also something I've asked about in the past
Daniel Klein
Daniel Klein•4w ago
Ye Unfortunately I found out the the hard way and monorepo did its own part in escalating the difficulty but finally after 2 days of typescript hell I got it working in acceptable manners 😄
Craig
Craig•2w ago
Try something like this:
interface Env {
UPLOADER: Fetcher<import("../autotranscriber/src/").Uploader>;
interface Env {
UPLOADER: Fetcher<import("../autotranscriber/src/").Uploader>;
(Where that Uploader is the exported class name at that relative dir)

Did you find this page helpful?