Typed Bindings
Declare resources in config, get Worker Env types automatically. No codegen step, no generated files, and no runtime dependency needed for the typing itself.
How it works
Section titled “How it works”import { kv, queue, d1, worker, workerEnv } from "wrangler-deploy";
export const api = workerEnv({ DB: d1("database"), CACHE: kv("cache"), QUEUE: queue<{ type: string }>("tasks"), BACKEND: worker("backend"),});import type { api } from "../wrangler-deploy.config.ts";type Env = typeof api.Env;Env resolves to the Worker runtime shape inferred from the config:
{ readonly DB: D1Database; readonly CACHE: KVNamespace; readonly QUEUE: Queue<{ type: string }>; readonly BACKEND: Fetcher;}Type mapping
Section titled “Type mapping”| Resource | Marker | Runtime type |
|---|---|---|
| D1 | d1() | D1Database |
| KV | kv() | KVNamespace |
| Queue | queue<T>() | Queue<T> |
| Hyperdrive | hyperdrive() | Hyperdrive |
| R2 | r2() | R2Bucket |
| Worker | worker() | Fetcher |
| Workflow | workflow<P>() | Workflow<P> |
| Secret | secret() | string |
No codegen, no runtime helper required
Section titled “No codegen, no runtime helper required”The types are resolved at compile time through TypeScript’s conditional type system. No build step, no generated files, and no Effect-like runtime library. Change a binding name in the config and TypeScript catches mismatches everywhere.
Enriched markers at runtime
Section titled “Enriched markers at runtime”In local development (wd dev), resource markers don’t have access to actual Cloudflare IDs until apply runs. The enrichMarkers() function attaches output from state to markers at runtime:
import { enrichMarkers, loadStateOutputs } from "wrangler-deploy";import type { ResourceMarker } from "wrangler-deploy/typed";
export function onRequestGet(request: Request, env: Env, ctx: ExecutionContext) { // env.DB has the binding, but what about the database ID? // enrichMarkers mutates the marker objects in place enrichMarkers(env.DB.__marker, env.__state);
// Now the marker has output attached console.log(env.DB.__marker.output?.id); // "abc123..."
// Or get all outputs as a flat object const outputs = loadStateOutputs(env.__state); console.log(outputs["database"]?.id);}The output property contains the real Cloudflare resource IDs, secrets, and connection strings from state. This is useful for:
- Debugging which real resource a binding points to
- Accessing D1 database IDs for direct SQL connections
- Reading R2 bucket names for direct uploads
- Conditional logic based on resource properties