Daniel Pérez
Daniel Pérez

Reputation: 1992

Inherit from react component

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

Answers (1)

Nitzan Tomer
Nitzan Tomer

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.


Edit

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

Related Questions