I'm working on creating a TypeScript friendly NPM package but I'm having trouble passing common HTML attributes as props like className
and style
to my component. I was hoping to not have to manually add each attribute to my list of props by extending an interface with all the desired props. My simplified component looks like this:
import React, { Key, ReactElement } from "react";
interface MyComponentProps extends React.HTMLAttributes<HTMLDivElement> {
customText: string;
uniqueKey?: Key;
}
export function MyComponent({uniqueKey, customText, ...props}: MyComponentProps): ReactElement {
return (
<div key={uniqueKey} {...props}>{customText}</div>
);
}
I created a uniqueKey
prop since it can't be named just key
(same with ref
). I tried to expand a props
parameter to pass arbitrary props to my component, but it doesn't seem to make a difference. I import this component into my project and try to call it like:
<MyComponent customText="Hello World" uniqueKey={123} className="myClass" />
I get the error: Property 'className' does not exist on type 'MyComponentProps'.
I was hoping this would work since MyComponentProps
extends HTMLAttributes
which has the props I want like className
and style
.
My index.d.ts
file looks like:
import React, { Key, ReactElement } from "react";
interface MyComponentProps extends React.HTMLAttributes<HTMLDivElement> {
customText: string;
uniqueKey?: Key;
}
export declare function MyComponent({ uniqueKey, customText, ...props }: MyComponentProps): ReactElement;
export {};
The easiest way to get the available props for a specific HTML element is by using JSX.IntrinsicElements
.
type MyComponentProps = JSX.IntrinsicElements['div'] & {
customText: string;
uniqueKey?: Key;
}
Under the hood, JSX.IntrinsicElements['div']
is the following type.
React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>