Cloudflare WorkerのRPC Bindingをmonorepoかつ型付きでやるtips
皆さん、CloudflareでWorkerをService Bindingする時、こう思ったことはないですか?
wrangler typesで生成されたworker-configuration.d.tsにRPC Bindingの適切な型がねぇ、と。
env.HogeService.fetch()しか無い、定義した関数がintellisenseに出てこない。めんどい。私はずっとそう思っていました。
しかし7月29日にリリースされたwrangler@4.26.1にて、これが解決されました。やったぜ。
tl;dr
wranglerのglobal option, --configを使う[1]
wrangler types -c ./wrangler.jsonc -c ../hoge-service/wrangler.jsonc
生成される型定義ファイル
declare namespace Cloudflare {
interface Env {
HogeService: Service<typeof import("../hoge-service/src/index").default>
}
}
interface Env extends Cloudflare.Env {}
これで、primary以降に指定したworker(wrangler.jsonc)を"型付きで"生成できる。
formatはこんな感じ
wrangler types -c <PrimaryWorker Config file path> [-c <RPC Worker Config file path>]...
🎉😀🎉
何故これが良いのか
👍 localで実行した時の警告文が出なくなる
❓ Your types might be out of date. Re-run `wrangler types` to ensure your types are correct.
👍 グローバルな型定義を維持出来る
例えば...
import type HogeServiceType from "@project/HogeService"
declare namespace Cloudflare {
interface Env {
HogeService: HogeServiceType
}
}
interface Env extends Cloudflare.Env {}
このようなコードにしてしまうと...
-
module扱いになってしまい、全てのファイルで
worker-configuration.d.tsをimportしなくてはいけなくなる -
worker-configuration.d.tsでのambient 宣言(RpcTarget, WorkerEntrypoint)が参照不能になる -
従来の
@cloudflare/worker-typesはworker以外のために公開されるようになったため、公式推奨構成では無くなってしまう
// 型エラー(型定義ファイルがmoduleになっているため参照不能)
import { RpcTarget, WorkerEntrypoint } from 'cloudflare:workers';
// module化しているためEnvの他にR1/D1/KV/Queueと言った型もimport必須
import type { Env } from '../worker-configuration.d.ts';
export default class extends WorkerEntrypoint<Env> {
async fetch(): Promise<Response> {
return new Response('Hello World!');
}
async add(a: number, b: number) {
return a + b;
}
}
といった余りにも重い制約が課されてしまいます。コレジャナイ感すごい。
まとめ
wranglerのversionをbumpしよう。
補足(従来のやり方)
versionup出来ない等の事情があっても、表題の要件は達成できます。
-
@cloudflare/workers-typesをinstallする -
tsconfigのcompilerOptions.typesに
@cloudflare/workers-typesを含める
{
"compilerOptions": {
"types": ["@cloudflare/workers-types"],
},
}
- typed importをする
import type HogeServiceType from '@project/hoge-service';
interface Env {
HogeService: Service<HogeServiceType>
}
-
worker-configuration.d.tsがmoduleになるためimportしなくてはいけない -
wrangler typesを実行してはいけない
このような制約は変わりません。
補足2
turborepoやhono等で型チェックが通らなくなる(場合がある?)、らしいです。issue comment
その場合は補足の方法でなんとかなりそうです。多分。
でももっと他に良い方法もあるかも。たぶん。
Discussion