Open piotrkulpinski opened 1 year ago
This is a working workaround:
import type {
V2_ServerRuntimeMetaArgs,
V2_ServerRuntimeMetaDescriptor,
} from "@remix-run/server-runtime";
import type { UseDataFunctionReturn } from "remix-typedjson";
export type V2TypedMetaFunction<Loader> = (
args: Omit<V2_ServerRuntimeMetaArgs, "data"> & {
data: UseDataFunctionReturn<Loader> | undefined;
}
) => V2_ServerRuntimeMetaDescriptor[];
export const meta: VV2TypedMetaFunction<typeof loader> = ({ data }) => {}
--- EDIT ---
Obviously, this package does not touch the de-serialization handled magically by Remix for the meta
function, so for the meta function we don't have access to the types provided by remix-typedjson
.
The correct type thus would be:
import type {
DataFunctionArgs,
SerializeFrom,
V2_ServerRuntimeMetaArgs,
V2_ServerRuntimeMetaDescriptor,
} from "@remix-run/server-runtime";
import type { TypedJsonResponse } from "remix-typedjson";
export type V2TypedMetaFunction<
Loader extends (args: DataFunctionArgs) => Promise<TypedJsonResponse>
> = (
args: Omit<V2_ServerRuntimeMetaArgs, "data"> & {
data: SerializeFrom<PromiseReturnType<PromiseReturnType<Loader>["typedjson"]>> | undefined;
}
) => V2_ServerRuntimeMetaDescriptor[];
// helper
export type PromiseReturnType<T extends (...arguments_: any) => Promise<any>> = PromiseType<
ReturnType<T>
>;
which uses the SerializeFrom
type provided by Remix
Since this has been released in remix, there is still no alternative for remix-typedjson
is this still planned?
Although I do plan to deprecate this package in favor of Single Fetch in Remix, I may be able to come up with a workaround.
Sooo... I'm curious. How exactly did TypedMetaFunction not work?
export const meta: TypedMetaFunction<typeof loader> = ({ data }) => {
let page = data?.job.title || 'Job not found';
return [{ title: `${page} | Portal` }];
};
This seems to work. In this case the value is a plain string. Anything that requires deserialization probably won't work though?
I did find an interesting case; data.job
is inferred as Job
, as the loader in question either throws or returns a Job
. However, in reality, if the user hits a 404, data
is undefined. Is this one of the ways it doesn't work? 😁
Unfortunately, the types "lied" to you. Sure your types look right, but the data was still the original JSON, and not deserialized by typedjson
. So your native types like Date
would still be strings even though the type said they were Date
.
This was because there was no extension point in Remix for me to add the deserialization, unlike useTypedLoaderData
, where I can do the conversion from useLoaderData
before returning.
I'll create a helper function that wraps your meta so you get the converted types.
Hi, Love the project! Thanks for working on this.
I just started implementing some of the new Remix APIs that are coming in 2.0 and typescript is throwing errors with the
TypedMetaFunction
as it's using the oldV1_HtmlMetaDescriptor
return type.Any chance to add
V2_TypedMetaFunction
to fix that?Thanks!