🔥
Honoが返すJSONの型を明示したい!
結論
ReturnType<typeof c.json<...>>
はじめに
Hono、便利ですよね。
しかし、Honoを使っていると、c.json()
が返すJSONの型を明示したいときがあります。
export type Ok<T> = { ok: true; value: T };
export type Err<E = string> = { ok: false; error: E };
export type Result<T, E = string> = Ok<T> | Err<E>;
私は、このようなResult
型をよく使います。Honoで返すJSONもこのResult
型に沿うようにしています。
const app = new Hono().get("/", async (c) => {
const res = await processPossibleFail();
if (!res.success) {
return c.json({ ok: false, error: res.error }, 500);
}
return c.json({ ok: true, value: res.value }, 200);
});
このような感じです。これはreturnが2箇所なのでまだいい方ですが、早期returnの数が増えてくると、すべてのreturnで期待した型になっているか不安になってきます。ひとつずつsatisfies
などでチェックするのも面倒です。
そこで、ハンドラが返す型を明示的に指定したいと思いました。
例
const app = new Hono().get(
"/",
async (c): Promise<ReturnType<typeof c.json<Result<{ text: string }>>>> => {
const res = await processPossibleFail();
if (!res.success) {
return c.json({ ok: false, error: res.error }, 500);
}
const text = res.value.text;
return c.json({ ok: true, value: { text } }, 200);
}
);
おわりに
調べても出てこなかったので記事にしたのですが、もしかしたらもっといい方法があるかもしれません。
ちなみに、毎回ReturnType<typeof c.json<...>>
と書くのは面倒なので、
type HonoJSON<T> = ReturnType<Context['json']<T>>
という風にしたかったのですが、ダメみたいです。
Discussion
ちなみに、
@hono/zod-openapi
を使えばこんなこと気にする必要なくなります。