6

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.

2 Answers 2

7
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.

Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.