Reputation: 6102
I'm trying to write an abstract ReactJS class, then extend it. I'll thus need to extend its props
and state
(as far as I understand; I'm new to React).
Based on Nitzan's post showing how to extend props
from a base class, I made an abstract class Animal
:
import * as React from "react";
export interface AnimalProps {
isHibernatory: boolean;
}
export interface AnimalState {
shouldHibernate: boolean;
}
// TS2322: Type '{ shouldHibernate: boolean; }' is not assignable to type 'Readonly<S>'.
export abstract class Animal<P extends AnimalProps, S extends AnimalState>
extends React.Component<P, S> {
constructor(props: P) {
super(props);
this.state = {
shouldHibernate: props.isHibernatory
};
}
}
... And also made a class Cat
that extends it:
import * as React from "react";
import {AnimalProps, AnimalState, Animal} from "./Animal";
export interface CatProps extends AnimalProps {
isHairless: boolean;
}
export interface CatState extends AnimalState {
shouldSeekWarmth: boolean;
}
export class Cat extends Animal<CatProps, CatState> {
constructor(props: P) {
super(props);
this.state = {
willHibernate: props.isHibernatory,
shouldSeekWarmth: props.isHairless
};
}
}
However, as commented, the TypeScript compiler throws the error TS2322: Type '{ shouldHibernate: boolean; }' is not assignable to type 'Readonly<S>'
. I believe this is because it can't guarantee that S
will be readonly once it has extended AnimalState
. How else could I write this? Or am I missing a bigger picture?
Upvotes: 9
Views: 23739
Reputation: 5707
I tried to cast the anonymous object to Readonly<S>
and the error went away.
this.state = { shouldHibernate: props.isHibernatory } as Readonly<S>;
Upvotes: 7
Reputation: 15821
React prefers composition over inheritance, may be this is a viable approach in some plain JS patterns but this is not the case.
As you are new to React, take a look at https://reactjs.org/docs/composition-vs-inheritance.html
"At Facebook, we use React in thousands of components, and we haven’t found any use cases where we would recommend creating component inheritance hierarchies."
Upvotes: 10