Home > Blockchain >  Element is not assignable to type 'FC<ContainerProps>'
Element is not assignable to type 'FC<ContainerProps>'

Time:11-04

I've learning React/Ionic/Typescript by creating a project for myself and have stumbled on a situation that I'd like to understand better. I've created the following custom component:

import React from 'react';
import './CardContainer.css';

interface ContainerProps {
    position?: string;
    content?: string;
}

const CardContainer: React.FC<ContainerProps> = ({ position = "right", content = "n/a" }) => {
    let cardOutput = <></>
    if ( position.trim().toLowerCase() === "right" ) {
        cardOutput = <><div className="ion-float-right" >{content}</div><div className="clear-right"></div></>
    } else if ( position.trim().toLowerCase() === "left" ) {
        cardOutput = <div className="ion-float-left">{content}</div> 
    } else if ( position.trim().toLowerCase() === "full" ) {
        cardOutput = <div className="">{content}</div>
    }
    else if ( position.trim().toLowerCase() === "empty" ) { 
        cardOutput = <div className="">&nbsp;</div> 
    }
    return( cardOutput );
};

export default CardContainer;

This works as expected. However, I figured it was a bit unnecessary to dump the results into a variable and then return the variable at the end. So, I changed this to return the relevant jsx block under each conditional statement instead. See below:

import React from 'react';
import './CardContainer.css';

interface ContainerProps {
    position?: string;
    content?: string;
}

const CardContainer: React.FC<ContainerProps> = ({ position = "right", content = "n/a" }) => {

    if ( position.trim().toLowerCase() === "right" ) {
        return( <><div className="ion-float-right" >{content}</div><div className="clear-right"></div></> )
    } else if ( position.trim().toLowerCase() === "left" ) {
        return( <div className="ion-float-left">{content}</div> )
    } else if ( position.trim().toLowerCase() === "full" ) {
        return( <div className="">{content}</div> )
    }
    else if ( position.trim().toLowerCase() === "empty" ) { 
        return( <div className="">&nbsp;</div> )
    }
};

export default CardContainer;

However, this second code version will not compile and VS code gives the following error -which doesn't mean much to me at present:

Type '({ position, content }: PropsWithChildren) => "" | Element' is not assignable to type 'FC'. Type '"" | Element' is not assignable to type 'ReactElement<any, any> | null'. Type '""' is not assignable to type 'ReactElement<any, any> | null'.ts(2322)

I'm at a complete loss at to what I need to do to fix this, but would like to learn from this and understand what the "problem" is and why. It'd obviously be even better to be able to fix the issue too.

Thanks.

CodePudding user response:

If all the if/else if conditions fail then the component will return undefined.

You can simply return null at the end to fix the error and to not render anything if all conditions fail.

const CardContainer: React.FC<ContainerProps> = ({ position = "right", content = "n/a" }) => {

    if ( position.trim().toLowerCase() === "right" ) {
        return( <><div className="ion-float-right" >{content}</div><div className="clear-right"></div></> )
    } else if ( position.trim().toLowerCase() === "left" ) {
        return( <div className="ion-float-left">{content}</div> )
    } else if ( position.trim().toLowerCase() === "full" ) {
        return( <div className="">{content}</div> )
    }
    else if ( position.trim().toLowerCase() === "empty" ) { 
        return( <div className="">&nbsp;</div> )
    }

    return null;
};

This is not an issue in your first snippet because let cardOutput = <></> will return the fragment instead of undefined.

  • Related