Open cherewaty opened 5 months ago
I believe it's because the generic only allows to extends
from LoaderFunction
.
Yeah, also it makes sense. You're rendering meta tags on the server, so in this case you should only rely on data provided by the loader.
Yeah, also it makes sense. You're rendering meta tags on the server, so in this case you should only rely on data provided by the loader.
This might not be the whole story since Remix also supports a SPA mode, I believe the meta function should work with clientLoader
as well.
I've got a clunky workaround in place that gets me correct type information for data
, but:
meta
, since MetaFunction
doesn't match@remix-run/node
, which feels conceptually wrong for SPA modeimport { SerializeFrom } from "@remix-run/node";
export const meta = ({ data }: { data: SerializeFrom<typeof clientLoader> }) => {
return [{ title: data.task.name }];
};
I've got a clunky workaround in place that gets me correct type information for
data
, but:
- doesn't add type protection for the return of
meta
, sinceMetaFunction
doesn't match- Requires importing a type from
@remix-run/node
, which feels conceptually wrong for SPA modeimport { SerializeFrom } from "@remix-run/node"; export const meta = ({ data }: { data: SerializeFrom<typeof clientLoader> }) => { return [{ title: data.task.name }]; };
I created a new type until Remix fix that issue. When Remix will fix this issue, I'll only have to replace the occurrences of "ClientMetaFunction" by "MetaFunction" and update the imports.
import { SerializeFrom } from '@remix-run/node'
import { MetaDescriptor, MetaArgs } from '@remix-run/react'
type ClientMetaFunction<T> = (args: MetaArgs & { data: SerializeFrom<T> }) => MetaDescriptor[]
export const meta: ClientMetaFunction<typeof clientLoader> = ({ data }) => {
return [{ title: `My page ${data.myParam}` }]
}
Let me know if I'm wrong.
Reproduction
https://stackblitz.com/edit/remix-run-remix-qggawd?file=app%2Froutes%2Fhello.tsx
System Info
Used Package Manager
yarn
Expected Behavior
The docs for
meta
describe a TypeScript-friendly approach for usingloader
data inmeta
: https://remix.run/docs/en/main/route/meta#dataI have a Remix app in SPA mode using
clientLoader
s. I tried to take a similar approach to use typedclientLoader
data inmeta
:Actual Behavior
The code posted successfully passes the
task
with nameHello
tometa
, and it gets applied to the document title in the browser. But TypeScript reports that'data' is of type 'unknown'
inside ofmeta
.