0

I am creating a component which will be extended in future, for that i need to make it more generic.

I have a requirement something like below.

I have a class Base which accepts properties of type 'cell' and 'phone'.

I want to extend that in NewBase class and support new property newType.

The error I am getting is

[ts] This condition will always return 'false' since the types '"cell" | "phone"' and '0' have no overlap.

I am not getting enough ideas to extend the interface to support the new class Please Help...

export interface IBaseType {
    type: 'cell' | 'phone' 
} 
export class Base extends React.Component<IBaseType > {
    public render() {
        const { name, type } = this.props;
        return (() => {
            switch (type) {
                case 'cell': return <h1>Cell</h1>
                case 'phone': return <h1>Phone</h1>
            }
        })()
    } 
}

interface NewType extends Omit<IBaseType, 'type'>  {
    type: 'newType' | IBaseType['type']
 }

class NewBase extends Base {
    constructor(props: NewType){}
    public render(){
       if(this.props.type === 'newType') {
          return <h1>Hi i am new type</h1>
       }
       return super.render();
    }
}
1
  • 1
    That's not Component's signature for generics. If you peek in the typedef file you'll see it's React.Component<Props, State>. Also, Facebook recommends composition over inheritance Commented Oct 30, 2018 at 11:49

1 Answer 1

4

The type of this.props is determined by the props type argument you pass to React.Component. In this scenario where NewBase extends Base and Base extends React.Component<IBaseType>, the type of this.props is still IBaseType, which explains the error. If you want to be able to define subclasses of Base that have different props types, you'll need to add a type parameter to Base for the props type. Something like this may work for you:

interface ICommonType {
    type: string;
}
export interface IBaseType {
    type: 'cell' | 'phone' 
} 
export class Base<P extends ICommonType = IBaseType> extends React.Component<P> {
    public render() {
        const { name, type } = this.props;
        return (() => {
            switch (type) {
                case 'cell': return <h1>Cell</h1>
                case 'phone': return <h1>Phone</h1>
            }
        })()
    } 
}

interface NewType extends Omit<IBaseType, 'type'>  {
    type: 'newType' | IBaseType['type']
 }

class NewBase extends Base<NewType> {
    public render(){
       if(this.props.type === 'newType') {
          return <h1>Hi i am new type</h1>
       }
       return super.render();
    }
}
Sign up to request clarification or add additional context in comments.

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.