Reputation: 1992
Hello I'm using typescript + react, and I want to have a base class and several components inherit from the base class.
import * as React from "react";
interface IBaseProps {
title: string;
}
class Base<P extends IBaseProps, S> extends React.Component<P, S> {
public props: IBaseProps;
public render() {
return (
<h1> Generic Class {this.props.title} </h1>
);
}
}
interface IChildProps extends IBaseProps {
message: string;
}
class Child extends React.Component<IChildProps, undefined> {
public render() {
return (
<h1> Child Class {this.props.title} {this.props.message} </h1>
);
}
}
But when compiling it throws an error:
TS2415: Class 'Base<P, S>' incorrectly extends base class 'Component<P, S>'.
Types of property 'props' are incompatible.
Type 'IBaseProps' is not assignable to type 'Readonly<{ children?: ReactNode; }> & Readonly<P>'.
Type 'IBaseProps' is not assignable to type 'Readonly<P>'.
The problem is not inheriting, even this got me the error
export class Base<P, S> extends React.Component<P, S> {
public props: IBaseProps;
public render() {
return (
<h1> Generic Component </h1>
);
}
}
I'm using typescript v2.3.4
, in case it matter
Upvotes: 1
Views: 726
Reputation: 164129
There's no need to define the props
member twice, it's enough to do so in the base class:
class Base<P extends IBaseProps, S> extends React.Component<P, S> {
public props: IBaseProps;
...
}
class Child extends React.Component<IChildProps, undefined> {
public render() {
...
}
}
The type of Child.props
will be IChildProps
because that's what you passed as the generic constraint.
But you don't even need to define it in the base class because React.Component
will already do that for you, so it should just be:
class Base<P extends IBaseProps, S> extends React.Component<P, S> {
public render() {
...
}
}
class Child extends React.Component<IChildProps, undefined> {
public render() {
...
}
}
And you will still have this.props
(with the right type) in all components.
In your original code you had this:
class Base<P extends IBaseProps, S> extends React.Component<P, S> {
public props: IBaseProps;
...
}
But the definition for React.Component is:
class Component<P, S> {
...
props: Readonly<{ children?: ReactNode }> & Readonly<P>;
...
}
Which means that you have overridden the props
member with a type that does not match, and that's what the error says.
Upvotes: 2