I have several components that extend the native functionality of inputs, buttons, forms, etc., but I find it tedious to have to include every event handler and prop when the team needs it.
I tried simply making the component prop type extend the native prop type and then using object propagation to automatically apply all the native props. The next problem is that custom props are not supported and should not be applied to native elements.
To solve this problem, the only solution I found was to copy the name of each custom prop in the component parameters like this: {customProp1, customProp2, ...nativeProps}. However, this solution, while much better than having to add all native props, forces me to copy all the props and I lose the props. I like the prefix used to distinguish props from local variables.
Is there a clever way to filter out native props from custom props?
Example of what I want to achieve:
import React from 'react' type Props = { color: string, } const Button = ({...props}: Props, {...nativeProps} : React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>) => { return ( <button {...nativeProps} style={{backgroundColor: props.color}} /> ) } export default Button
My current best solution involves copying each prop name and using the spread operator on the remaining props.
import React from 'react' type CustomProps = { color: string, label: React.ReactNode, name: string, } type Props = CustomProps & Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, keyof CustomProps>; const Button = ({color, label, ...props}: Props) => { return ( <> {label} <button {...props} style={{backgroundColor: color}} /> </> ) } export default Button
P粉8262835292024-03-31 16:20:38
Have you tried using interface
with extends
?
import React from 'react'; interface IButtonProps extends React.DetailedHTMLProps< React.ButtonHTMLAttributes, HTMLButtonElement > { color: string; } const Button = ({ color, ...props }: IButtonProps) => { return ; }; export default Button;
Otherwise, you can nest native button props:
import React from "react"; interface IButtonProps { color: string; buttonProps?: React.DetailedHTMLProps< React.ButtonHTMLAttributes, HTMLButtonElement >; } const Button = ({ buttonProps, ...props }: IButtonProps) => { return ; }; const App = () => { return ; }; export default App;