When using forwardRef with generics, I get Property 'children' does not exist on type 'IntrinsicAttributes'
or Property 'ref' does not exist on type 'IntrinsicAttributes'
.
https://codesandbox.io/s/react-typescript-0dt6d?fontsize=14
Relevant code in CodeSandbox link above replicated here:
interface SimpleProps<T extends string>
extends React.HTMLProps<HTMLButtonElement> {
random: T;
}
interface Props {
ref?: React.RefObject<HTMLButtonElement>;
children: React.ReactNode;
}
function WithGenericsButton<T extends string>() {
return React.forwardRef<HTMLButtonElement, Props & SimpleProps<T>>(
({ children, ...otherProps }, ref) => (
<button ref={ref} className="FancyButton" {...otherProps}>
{children}
</button>
)
);
}
() => (
<WithGenericsButton<string> ref={ref} color="green">
Click me! // Errors: Property 'children' does not exist on type 'IntrinsicAttributes'
</WithGenericsButton>
)
A potential solution is suggested here but not sure how to implement in this context: https://github.com/microsoft/TypeScript/pull/30215 (Found from https://stackoverflow.com/a/51898192/9973558)
So the main problem here is that you're returning the result of React.forwardRef
in your render, which isn't a valid return type for the render func. You'd need to define the forwardRef result as it's own component, and then render that inside your WithGenericsButton higher order component, like so:
import * as React from "react";
interface SimpleProps<T extends string> {
random: T;
}
interface Props {
children: React.ReactNode;
color: string;
}
function WithGenericsButton<T extends string>(
props: Props & SimpleProps<T> & { ref: React.Ref<HTMLButtonElement> }
) {
type CombinedProps = Props & SimpleProps<T>;
const Button = React.forwardRef<HTMLButtonElement, CombinedProps>(
({ children, ...otherProps }, ref) => (
<button ref={ref} className="FancyButton" {...otherProps}>
{children}
</button>
)
);
return <Button {...props} />;
}
const App: React.FC = () => {
const ref = React.useRef<HTMLButtonElement>(null);
return (
<WithGenericsButton<string> ref={ref} color="green" random="foo">
Click me!
</WithGenericsButton>
);
};
If you put that in a sandbox or playground you'll see that props
is now typed correctly including a random
prop of T
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With