RemixのloaderでDate型がstringになるのを防ぐ
はじめに
今回紹介する方法はRemix標準で修正するのではなく、remix-typedjsonというライブラリを使用する方法を取っています。
また、私の使用している環境は以下のようになっています。
{
"@remix-run/node": "^1.13.0",
"@remix-run/react": "^1.13.0",
"@remix-run/serve": "^1.13.0",
"remix-typedjson": "^0.1.7"
}
それでは、さっそく見ていきましょう
パッケージのインストール
pnpm add remix-typedjson
loaderの修正
Remixは幾つかのバージョンを経て、loaderからの型推論が進化しています。そのため、remix-typedjsonにも書いてある以下のように✅がついている書き方ではないと正しく動作しません。
❌ export const loader: LoaderFunction = async ({request}) => {}
✅ export const loader = async ({request}: LoaderArgs) => {}
✅ export async function loader({request}: LoaderArgs) {}
戻り値を返す際は@remix-run/nodeのjsonではなく、remix-typedjsonのtypedjsonを使用します。
import { typedjson } from "remix-typedjson";
return typedjson(
{ greeting: 'hello', today: new Date() },
// ResponseInit is optional, just like the `json` helper
{ headers: { 'set-header': await commitSession(session) } },
)
useLoaderDataの修正
以下のように @remix-run/reactのuseLoaderDataではなく、remix-typedjson の useTypedLoaderData というものを使用します。
import { useTypedLoaderData } from "remix-typedjson";
const loaderData = useTypedLoaderData<typeof loader>()
他にもたくさん
全部紹介すると長くなってしまうので、ここからはRemix標準のものを remix-typedjsonライブラリに置き換える場合の変換表としてご紹介します。
| Remix | remix-typedjson |
|---|---|
| useActionData | useTypedActionData |
| useRouteLoaderData | useTypedRouteLoaderData |
| useFetcher | useTypedFetcher |
| redirect | redirect |
| MetaFunction | TypedMetaFunction |
もっと詳しく知りたいという方は以下がリポジトリになるので是非見てみましょう!
内包されないの?
このライブラリの機能は普通に便利なのでRemixに内包されて欲しいですが、現状はないように感じます。理由は以下のIssueのコラボレーターの方の発言です。
他にもRemixで remix-typedjson が使用している superjson というライブラリを内包するようにするという議論がありますが今のところ進捗はありません。
また、議論の作者であるsergiodxaさんが以下のようなメッセージを議論の最初に追記しています。
Note: I no longer think this is something that should be added, also @kiliman remix-typedjson is a great and simple to use tool.
最後に
prismaなどをloader内で使用している際にDate型があるとString型になってしまい、エディター上のエラーがよく出ていてうーんと思っていたので、そういう方のお役に立てば幸いです
Discussion
useLoaderDataのレスポンスの型がこうなってしまって悩んでいたところ、この記事で解決しました!お役に立てたようで何よりです!
ここまで書かれてあるの助かります🙇🏻♂️👏🏻