RemixのuseLoaderDataのJsonifyObject型に対しての対応方法

RemixのuseLoaderDataのJsonifyObject型に対しての対応方法
この記事のポイント
  • @remix-run/reactのuseLoaderDataを使うとJsonifyObject型が返ってくる
  • remix-typedjsonを使うとloaderで渡したデータの型が取得できる

TypeScriptでRemixのuseLoaderDataを使うと困るのがJsonifyObject型が返ってくること。

JsonifyObjectが返却されてコンポーネントで使うとタイプエラー・・、は多くの人が経験あるのではないでしょうか。 型の不一致が起きてしまうと都合が悪いので、remix-typedjsonを使って本来の型でデータを取得する方法を紹介します。

remix-typedjsonとは?

remix-typedjsonは、Remixアプリケーションで使用するためのsuperjsonの代替パッケージです。superjsonがサポートする型のサブセットを扱いつつ、より高速で、サイズも小さいのが特徴です。

remix-typedjson
kiliman/remix-typedjson: This package is a replacement for superjson to use in your Remix app. It handles a subset of types that `superjson` supports, but is faster and smaller.

そもそもsuperjsonとは、JSONにはない追加の型(例えば、日付、正規表現、マップ、セットなど)をサポートすることで、JavaScriptのデータをより豊富にシリアライズおよびデシリアライズできるようにするライブラリです。

superjsonを使用することで、開発者はJSONで直接サポートされていないデータ型を扱う際の多くの制限を克服でき、アプリケーション間でのデータの受け渡しがより柔軟でエラーが少なくなります。

superjson
blitz-js/superjson: Safely serialize JavaScript expressions to a superset of JSON, which includes Dates, BigInts, and more.

@remix-runを使った場合

まずはremix-typedjsonを使わずに@remix-runを使った場合です。

useLoaderDataを使うとJsonifyObject型が返ってきます。

import { json } from '@remix-run/node'
import { useLoaderData } from '@remix-run/react'
export async function loader() {
return json({
user: {
id: 1,
name: 'CodeConnect',
},
})
}
export default function Index() {
const { user } = useLoaderData<typeof loader>()
// userの型
// JsonifyObject<{
// id: number
// name: string
// }>
}

JsonifyObject型に対しての対応方法

もしJsoninfyObjectを使って良ければ対応する方法もあります。
本来の型ではタイプエラーになってしまうのでSerializeFromを使います 。

import { SerializeFrom } from '@remix-run/node'
interface Props {
user: SerializeFrom<{
id: number
name: string
}>
}

SerializeFromを使うことでJsonifyObject型でラップされた型を取得することができます。

remix-typedjsonを使った場合

次にこの記事の本題、remix-typedjsonを使った方法です。

まずはremix-typedjsonをインストールします。

Terminal window
yarn add remix-typedjson

remix-typedjsonを使うと、loaderの返り値にJsonifyObjectを使わずに型を指定できます。

jsonメソッドの代わりにtypedjson、useLoaderDataの代わりにuseTypedLoaderDataを使います。

import { typedjson, useTypedLoaderData } from 'remix-typedjson'
export async function loader() {
return typedjson({
user: {
id: 1,
name: 'CodeConnect',
},
})
}
export default function Index() {
const { user } = useTypedLoaderData<typeof loader>()
// userの型
// {
// id: number
// name: string
// }
}

これでJsonifyObject型にはならずSerializeFormを使う必要もなくなります。

まとめ

普通にRemixで実装していくと、絶対にこの問題にぶち当たるんじゃない?というくらいJsonifyObject型にはまります。

remix-typedjsonは公式のパッケージではないので、絶対に使うのを推奨とは言えません。 メリットとデメリットを考えたうえでremix-typedjsonの使用を検討されてみてはいかがでしょうか。

Related Posts

Collaborative Innovation
for Your Growth

合同会社コードコネクトはフロントエンドを中心としたWeb開発を得意としています。
このようなシステム開発にご興味のある方、またはお困りの方はお気軽にお問い合わせください。

  • JamstackをベースとしたWebサイトの構築
  • Reactなどを用いたアプリケーションの開発
  • 運用に耐えられるメンテナンス性を考慮したプロダクト開発
  • モダンで運用可能な開発環境の構築