Cloudflare Workersで動くコードを、TypeScript(JSDoc TSでも)で書く時には、型定義である@cloudflare/workers-typesを入れるのが基本。
それがないと、HTMLRewriterみたくグローバルにあるやつも見えないし、Requestの.cfプロパティも読めないし、KVNamespaceみたいな定義もないし、なぜかCloudflareだけが独自に実装してるcrypto.subtle.timingSafeEqual()も存在しないことになっちゃうから。
で、それをインストールするとき、何気なくこうしてません?
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"lib": ["esnext"],
"types": ["@cloudflare/workers-types"]
}
}
まあ間違ってはないけど、もしかしたら困るケースが出てくるかもしれない。
Compatiblity dates
wrangler.tomlにも似たような設定があるけど、この型定義にもある。
実は、@cloudflare/workers-typesというnpmのパッケージは、いくつかバージョン違いの型定義を公開してて、それがその名の通りCompatibility datesという特定日時でのスナップショットになってる。
@cloudflare/workers-typesって指定したときに参照される型定義は、実はもっとも古い日時のもので、それはなんと2021-11-03以前というだいぶ前の定義になってる。
なんとなく、そこは最新のやつが入ってくるんでは?って思ってたけど、真逆だった。
なので新しい定義がほしい場合は、@cloudflare/workers-types/2022-11-30のように指定する必要がある。
指定できる日時の一覧は、たぶんGitHubを見るのがよさそう・・・?
https://github.com/cloudflare/workerd/tree/main/npm/workers-types#compatibility-dates
というわけで
いつでも最新のものを使うようにしたい場合は、@cloudflare/workers-types/experimentalとする必要がある。
現時点での最新である2023-07-01を指定したいなと思ったけど、なぜかnpmに公開されてなかったので、これはIssueを建てておいた。
@cloudflare/workers-types/2023-07-01 is not published to npm? · Issue #1108 · cloudflare/workerd https://github.com/cloudflare/workerd/issues/1108
みんな困ってないのね。
何に困ってたか
const fd = await req.formData();
const image = fd.get("image");
このとき、imageがなぜかstring | nullになっちゃうというもの。
TSの本体であるdom.d.tsでは、FormDataEntryValue | nullになってるところ。(FormDataEntryValueは、File | string)
experimentalだと(というか、いずれかの日時を指定してやれば)、ちゃんと(File | string) | nullになる。