Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interface A incorrectly extends interface B

Given this interface:

interface Props extends React.HTMLAttributes<HTMLDivElement> {
  compLevel: string;
  property: Property;
  comps: Property[];
}

I'm having difficulties with the property attribute given that it already exists on HTMLAttributes as property?: string;:

Interface 'Props' incorrectly extends interface 'HTMLAttributes'. Types of property 'property' are incompatible. Type 'SerializedObject' is not assignable to type 'string'.

Renaming the attribute works though I'd rather not do that.What is a recommended interface to extend/approach to use so that I don't need to redefine className on my Props?

like image 799
Jan Klimo Avatar asked Jun 25 '26 08:06

Jan Klimo


2 Answers

What are you going to do with Props? You probably shouldn't use it in places that expect a React.HTMLAttributes<HTMLDivElement>. As stated, and treating the code as a complete example, I'd probably define Props like this:

// SimpleSpread<L, R> is a simplified version of what happens when you
// do an object spread like {...left, ...right} where left is of type L and
// right is of type R.  It is the type R, with any properties on L that
// don't exist in R.  (It doesn't work if a key in L is an optional property in
// R, which is why this is simplified)
type SimpleSpread<L, R> = R & Pick<L, Exclude<keyof L, keyof R>>;

// Define the props you want to spread into React.HTMLAttributes<HTMLDivElement>
interface PropsExtra {
  compLevel: string;
  property: Property;
  comps: Property[];
}

// Define Props
interface Props
  extends SimpleSpread<React.HTMLAttributes<HTMLDivElement>, PropsExtra> {}

This works by treating Props like PropsExtra with only those properties from React.HTMLAttributes<HTMLDivElement> that do not appear in PropsExtra. So this will end up overwriting the property property instead of extending it.

That will now have no error.


Do note that the following will be an error:

declare function acceptAttributes(attrs: React.HTMLAttributes<HTMLDivElement>);
declare const p: Props;
acceptAttributes(p); // error! p is not a React.HTMLAttributes<HTMLDivElement>

Because they differ in the types of the property property (heh), a value of type Props is no longer a valid React.HTMLAttributes<HTMLDivElement> value. Anything which expects the latter will not accept the former. You could then change the expected argument type of such functions, which will likely cascade outwards until this change touches more of your code base than you intended.

So it really depends on your use case if this will work for you. Good luck!

like image 95
jcalz Avatar answered Jun 27 '26 10:06

jcalz


You could use

interface Props extends Omit<React.HTMLAttributes<HTMLDivElement>, "property"> {
  compLevel: string;
  property: Property;
  comps: Property[];
}

to apply all other properties except for "property". That way it should consider the property "property" defined by you.

like image 27
Giovanni Dias Avatar answered Jun 27 '26 10:06

Giovanni Dias



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!