If I have a component,
import { FC } from 'react';
interface Props {
name: string;
}
const Home: FC<Props> = ({ name, ...rest }) => {
return (
<>
<div>{name}</div>
<input {...rest} type="text" />
</>
);
};
export default Home;
and try to use it like <Home name="testName" placeholder="test" />, my editor is mad giving red underline under placeholder.
Raw Error:
Type '{ name: string; placeholder: string; }' is not assignable to type 'IntrinsicAttributes & Props & { children?: ReactNode; }'.
Property 'placeholder' does not exist on type 'IntrinsicAttributes & Props & { children?: ReactNode; }'.
I tried extending the Props with HTMLAttributes but it didn't work.
interface Props extends HTMLAttributes<HTMLElement> {
name: string;
}
This has nothing to do with the rest operator.
interface Props { name: string; }
Your interface doesn't allow a placeholder attribute on the element.
If you want to pass through properties allowed on an input, then you have to include those properties on the interface.
interface Props extends React.ComponentPropsWithoutRef<"input"> {
name: string;
}
children?: ReactNode interface defined which can be extended.props for your component.const Home: FC<Props>. This means, You've extended the interface of React.FC with your Props definition. This means that you have{children: ReactNode, name: string} described to typescript as valid parameters that you are expecting. name,...rest. From Your interface definition this means, that ...rest will be only the property - children , because that's what You defined in your interface.\...rest spread operator. Since all of Your props go inside of button, you can extend your Props interface with React.ButtonHTMLAttributes<HTMLButtonElement>.interface Props extends React.ButtonHTMLAttributes<HTMLButtonElement> {
name: string;
}
const Home: FC<Props> = ({ name, ...rest }) => {
return (
<>
<div>{name}</div>
<input {...rest} type="text" />
</>
);
};
Update:
A VSCODE trick on inspecting what types does an element, or its property has is to simply hover on it.
