Reputation: 36189
Here is a simple example:
interface BaseProps {
name: string;
}
class BaseClass<P extends BaseProps> extends React.Component<P, void> {
}
interface SuperProps {
}
class SuperClass extends BaseClass<SuperProps> {
}
I'm expecting that SuperClass by default would have this.props.name
. But right now, I'm getting a compilation error, saying Type 'SuperProps' does not satisfy the constraint 'BaseProps'.Property 'name' is missing in type 'SuperProps'.
What am I doing wrong? I realize I can do SuperProps extends BaseProps
but that seems redundant here.
Upvotes: 6
Views: 4965
Reputation: 3607
Now say you couldn't modify BaseClass
(3rd party code) such that it takes a generic type i.e.
class BaseClass extends React.Component<BaseProps, void> {
}
You should still be able to redefine BaseClass
with extended prop types like so:
const SuperClass = BaseClass as React.ComponentClass<
BaseProps & {
somethingElse: string;
}
>;
Full e.g. where SomeInput
actually supports autoFocus
prop but it's exported prop type defs do not:
import { Input as SomeInput, InputPropsType as SomeInputPropsType } from 'somewhere';
const Input = SomeInput as React.ComponentClass<
SomeInputPropsType & {
autoFocus?: boolean;
}
>;
// Now passing `autoFocus` prop to `Input` should be fine
Upvotes: 0
Reputation: 12736
class BaseClass<P extends BaseProps> extends React.Component<P, void>
where <P extends BaseProps>
means any valid type which extends BaseProps
is assignable to BaseClass
. This is how the generics works.
Now, when you do
interface SuperProps {
}
class SuperClass extends BaseClass<SuperProps> {
}
You are assigning the type SuperProps
which does not extend the BaseProps
. That is the reason you are getting the error.
To overcome the error, as you said you either need to extend the BaseProps
interface or you can use intersection types. If you use intersection types then the complete example will look like:
export interface BaseProps {
name: string;
}
class BaseClass<P> extends React.Component<P & BaseProps, void> {
}
interface SuperProps {
}
class SuperClass extends BaseClass<SuperProps> {
render(): JSX.Element {
return (
<div>
{this.props.name} {/* Won't throw an error*/}
</div>
);
}
}
You can read more about advanced-types here.
Upvotes: 7