Open ni-hfriese opened 3 years ago
I recommend using React.HTMLAttributes<HTMLElement>
over React.HTMLProps<HTMLElement>
because this is a type of props for <nav/>
element. I'm not exactly sure in what context HTMLProps
should be used.
That resolved my specific issue, but I'm still curious if those two as
properties should be aligned to prevent issues in the future?
It also seems that HTMLProps<HTMLInputElement>
includes extra props (in contrast to HTMLAttributes<HTMLInputElement>
), like the disabled
and required
props.
So switching to HTMLProps
worked for me in some components, but not all—I can also Omit<HTMLProps<HTMLInputElement>, "as">
but it's not super nice.
Did you end up solving this differently?
Edit:
Hm so I found this and it looks like the way to go would be InputHTMLAttributes<HTMLInputElement>
. Works well on my end and I could clean up some old Omit<>
🎉
The only thing I'm not sure of is why some elements are missing their *HTMLAttributes
types, like ul
. I assume that it's because they don't have any other props beyond the HTMLAttribute
type (all other element-specific generics extend it), so for these I'd just use it directly: HTMLAttributes<HTMLUListElement>
.
@Andarist Thanks for your recommendation!
however, HTMLAttributes<HTMLElement>
doesn't really solve the issue, it just omits the property as
, and therefore the error will disappear. but, what if I wanted to use the prop as
? I can't! because it doesn't exist on the type we inherited from React.HTMLAttributes<HTMLElement>
.
as @robinmetral mentioned, I could solve the issue by using a specific type for each element (e.g. InputHTMLAttributes<HTMLInputElement>
). However, not every HTML element has a specific type, for instance, the div
element doesn't. I tried something like BaseHTMLAttributes
and it still omits the as
prop.
I suggest adding string
to the StyledComponent
's as
property so that it would be sth like as?: React.ElementType | string
If we can do that, we will be able to use HTMLProps<T>
again without the need to omit as
.
A more interesting solution would be if there's a way we can inherit the type StyledComponent
instead, and pass the HTML element type to get the proper attributes, for instance, StyledComponent<HTMLDivElement>
. I'm not sure if this is feasible though.
Just wanted to share my experience for anyone looking for the same issue.
I had a simple button component like this:
interface Props {
text?: string;
icon?: string;
}
const Button = ({
text,
icon,
...props
}: Props & HTMLProps<HTMLButtonElement>) => {
return (
<button {...props}>
{text && <span>{text}</span>}
{icon && <Icon icon={icon} />}
</button>
);
};
export default Button;
Wasn't even including an emotion css
prop yet, but was getting the following (slightly different) typescript error:
Type '{ children: ("" | Element | undefined)[]; accept?: string | undefined; acceptCharset?: string | undefined; action?: string | undefined; allowFullScreen?: boolean | undefined; ... 356 more ...; css: SerializedStyles; }' is not assignable to type 'ClassAttributes<HTMLButtonElement> & ButtonHTMLAttributes<HTMLButtonElement> & { css?: Interpolation<Theme>; }'.
Type '{ children: ("" | Element | undefined)[]; accept?: string | undefined; acceptCharset?: string | undefined; action?: string | undefined; allowFullScreen?: boolean | undefined; ... 356 more ...; css: SerializedStyles; }' is not assignable to type 'ButtonHTMLAttributes<HTMLButtonElement>'.
Types of property 'type' are incompatible.
Type 'string | undefined' is not assignable to type '"button" | "submit" | "reset" | undefined'.
Type 'string' is not assignable to type '"button" | "submit" | "reset" | undefined'.ts(2322)
Changing from HTMLProps
to HTMLAttributes
made the error go away. This stackoverflow post says that HTMLProps
has more stuff like ref
, though more information would be good.
Maybe you're supposed to use HTMLAttributes
when referring to a native dom element, and HTMLProps
when referring to a custom component that wraps a native dom element?
Current behaviour: Receive the following error when destructuring props onto an emotion/styled component.'s "as" property doesn't correspond with React.HTMLProps's "as" property (can also be HTMLButtonElement).
Type '{ children: (ReactNode | Element)[]; accept?: string | undefined; acceptCharset?: string | undefined; action?: string | undefined; allowFullScreen?: boolean | undefined; ... 356 more ...; key?: Key | ... 1 more ... | undefined; }' is not assignable to type '{ theme?: Theme | undefined; as?: ElementType<any> | undefined; }'. Types of property 'as' are incompatible. Type 'string | undefined' is not assignable to type 'ElementType<any> | undefined'. Type 'string' is not assignable to type 'ElementType<any> | undefined'.
This occurs on any tag you destruct functional component props on. styled.To reproduce: See Example Here.
Expected behaviour:
Environment information: