There's a small caveat with using JSX.IntrinsicElements, which is that it always includes a ref prop, even though it won't work in reality. This type is also referring to a legacy type for class-based components (LegacyRef<T>).
The better choice would be to use React.[Element]HTMLAttributes<HTML[Element]Element>, where [Element] is replace with the element type that your component wraps over, or the more explicit ComponentPropsWithRef<"button"> / ComponentPropsWithoutRef<"button">.
I prefer the former, since you don't have to think about updating the type of your Props in case you either wrap or unwrap your component forwardRef, which will return the correct type.
To explain further: Using JSX.IntrinsicElements will give you incorrect type information for props:
There's a small caveat with using
JSX.IntrinsicElements, which is that it always includes arefprop, even though it won't work in reality. This type is also referring to a legacy type for class-based components (LegacyRef<T>).The better choice would be to use
React.[Element]HTMLAttributes<HTML[Element]Element>, where[Element]is replace with the element type that your component wraps over, or the more explicitComponentPropsWithRef<"button">/ComponentPropsWithoutRef<"button">.I prefer the former, since you don't have to think about updating the type of your Props in case you either wrap or unwrap your component
forwardRef, which will return the correct type.To explain further: Using
JSX.IntrinsicElementswill give you incorrect type information for props:Passing anything to
refwill throw a warning in development mode:This is because it has not been forwarded by our wrapper component.
It also refers to the incorrect type
LegacyRef<T>which acceptsstringwhich are legacy as mentioned in the Ref and the DOM.It's by built-in JSX elements to be backwards-compatible with earlier versions of the React API.
However, using the
React.[Element]HTMLAttributes<HTML[Element]Element>instead:Gives us the correct type information; that
refis not present since it doesn't take any refs.If you'd like to accept a
refand pass it down to the underlying element, you want to useforwardRef:Note that the type for
refprop is nowRef<T>, which conforms correctly to whatuseRefandcreateRefreturns (RefCallback<T> | RefObject<T>).Hope this helps :-)