简体   繁体   中英

How to extend React class in typescript

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.

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 .

Now say you couldn't modify BaseClass (3rd party code) such that it takes a generic type ie

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM