Closed brianbolnick closed 1 year ago
Opened #29 with similar implementation to the main superjson repo.
I realize Decimal.js is pretty large, happy to discuss alternatives for supporting this properly.
Thanks 😄
Yes! Had this issue just now - have you figured out any other workaround in the meantime?
Here's the preliminary API I added to support custom types. This way you can register custom types without bloating the existing package. Essentially "pay-for-use". You only pay the cost of the custom type if you use it.
type CustomTypeEntry<T> = {
type: string
is: (value: unknown) => boolean
serialize: (value: T) => string
deserialize: (value: string) => T
}
export function registerCustomType<T>(entry: CustomTypeEntry<T>) {
customTypeMap.set(entry.type, entry)
}
Register the custom type in root.tsx once.
// root.tsx
import {
typedjson,
registerCustomType,
useTypedLoaderData,
} from "remix-typedjson";
import Decimal from "decimal.js";
registerCustomType({
type: "decimal",
is: (value: unknown) => value instanceof Decimal,
serialize: (value: Decimal) => value.toString(),
deserialize: (value: string) => new Decimal(value),
});
// route.tsx
export function loader() {
const d = new Decimal("1234567890123456789012345678901234567890");
return typedjson({ greeting: "Hello World", today: new Date(), d });
}
export default function Index() {
const loaderData = useTypedLoaderData<typeof loader>();
return (
<>
<h2>Loader Data</h2>
<pre>{JSON.stringify(loaderData, null, 2)}</pre>
<ul>
<li>today: {loaderData.today.toLocaleString()}</li>
<li>d instanceof Decimal: {loaderData.d instanceof Decimal ? "true" : "false"}</li>
<li>d: {loaderData.d.toFixed(0)}</li>
</ul>
</>
)
}
This has been published as v0.2.0
Thanks @kiliman! I've found this to work a bit more flawlessly for those looking for Decimal support (specifically prisma decimal):
registerCustomType({
type: "decimal",
is: (value: unknown) => Prisma.Decimal.isDecimal(value),
serialize: (value: Prisma.Decimal) => value.toJSON(),
deserialize: (value: string) => new Prisma.Decimal(value),
});
Yeah, this is flexible enough to support any type that the user needs, without bloating the main package.
For those of us using Prisma and the Decimal type, the current result of a serialized value is coming across as an object and not sticking with the true decimal.js type. 😄