How to properly type pre components? #1264
-
I have the following code: <ReactMarkdown
remarkPlugins={[remarkGfm]}
components={{
code: ({ node, className, children, ref, ...props }) => (
<Code {...props}>{String(children).replace(/\n$/, "")}</Code>
),
pre: ({
children: {
props: { node, className, children, ref, ...props },
},
}) => (
<CodeHighlight
language={(className ?? "").replace(/^language-/i, "")}
code={String(children).replace(/\n$/, "")}
{...props}
/>
),
}}
>
{body}
</ReactMarkdown> Typescript complains that I'm not sure I'm particularly clear on the API here and it's a small part of our codebase so I honestly just don't want to spend a ton of time trying to grok the underlying code. I would, however, like typescript to not complain (and not by just casting it as I have read the other issues/discussions on this topic, and I saw the linked upgrade (https://github.com/remarkjs/react-markdown/blob/main/changelog.md#remove-extra-props-passed-to-certain-components) and its not-very-clear upgrade suggestion ("create a plugin or use pre for the block" -- creating a plugin seems like a heavy lift for a user to replicate functionality that used to exist, and "use pre" is what I'm attempting here but obviously that's not as simple as is implied). What am I missing here? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
|
Beta Was this translation helpful? Give feedback.
-
Welcome @Californian! 👋
As @wooorm mentions
TypeScript is correct, import { isValidElement } from "react";
// ...
<ReactMarkdown
components={{
pre: ({ children }) => {
if (isValidElement(children)) {
const {
node,
className,
children: innerChildren,
ref,
...props
} = children.props;
return (
<CodeHighlight
language={(className ?? "").replace(/^language-/i, "")}
code={String(innerChildren).replace(/\n$/, "")}
{...props}
/>
);
}
},
}}
>
{body}
</ReactMarkdown>; example in sandbox: https://stackblitz.com/edit/github-porffk
How the |
Beta Was this translation helpful? Give feedback.
Welcome @Californian! 👋
As @wooorm mentions
JSX.IntrinsicElements['pre'] & ExtraProps
is the correct typeTypeScript is correct,
props
is not guaranteed to be onchildren
.children
could also benull
, a string, or a list of elements.You happen to have props on the documents you have tested, but don't rely on that assumption.
Instead consider something like: