reactjstypescriptnext.jsmdxjs

Passing props to `Image` only when they are not undefined


I'm building a blog site with MDX & NextJS. I'm defining a custom image component that will make use of the Next <Image> component. The issue I'm having is relatively small, but I've been struggling to find an answer to it.

The basic question is: If I have a variable of string | undefined, is there any way in React to only pass that variable to an optional prop if it's defined? I'm pretty new to React, so this might be something super basic.

My reasoning for needing this is that the custom MDX image component should take ImgHTMLAttributes<HTMLImageElement> as props. All of these props are defined as someType | undefined, which makes sense since HTML attributes are optional.

My issue comes in passing these props down to Next image. How do I pass the optional src, alt, width, and height props when they are defined in the original image but not when they aren't?

The specific error I'm getting is Type 'string | undefined' is not assignable to type 'string | StaticImport', which makes perfect sense.

I tried something like this:

    const src = props.src != undefined ? props.src : "";
    const alt = props.alt != undefined ? props.alt : "";
    const width = props.width != undefined ? props.width : "";
    const height = props.height != undefined ? props.height : "";

which was ugly, and also didn't really solve my problem. I don't want to be passing width when its undefined for example.


Solution

  • For the properties you need to supply defaults for instead of undefined, you use nullish coalescing, like this:

    export function ImageWrapper(props: ImageWrapperProps) {
        return <Image
            {...props}
            src={props.src ?? ValidDefaultSrc}
            alt={props.alt ?? ValidDefaultAlt}
        />;
    }
    

    The order is important there, first you spread out all of the properties from props, then override src and alt with versions with defaults. Those are the only two required properties in the props for the Next Image component.

    Playground link

    Note that I haven't just used "" as the defaults. The src and alt props are required on Image for a reason. I don't use Next.js, but it seems unlikely that src="" (in particular) is a valid value, and alt="" may be valid, but it's not accessible to users of screen readers and such. But I suspect you just used those in the question as placeholders.