18

I am using react dropzone to upload multi-image in my simple application. For showing which type of images are drop for that I make a separate component with TypeScript. But Next.js image src is showing error like Type:

'{ src: string; alt: string; }' is not assignable to type 'IntrinsicAttributes & ImageProps'. Type '{ src: string; alt: string; }' is not assignable to type 'ObjectImageProps'. Types of property 'src' are incompatible. Type 'string' is not assignable to type 'StaticImport'. 

RenderFiles.ts:

import { IFile } from "../../libs/types"; import { sizeInMb } from "../../libs/sizeInMb"; import { FunctionComponent } from "react"; import Image from "next/image" const RenderFile: FunctionComponent<{ file: IFile; }> = ({ file: { formate, sizeInBytes, name } }) => { return ( <div> <Image src={`/images/${formate}.png`} alt="image"/> <span>{name}</span> <span>{sizeInMb(sizeInBytes)}</span> </div> ); }; export default RenderFile; 

types.ts:

export interface IFile { name: string; sizeInBytes: number; formate: string | number; id?: string; } 

What is my mistake in src props?

6
  • are you loading the image from local path or any remote cdn? Commented Jun 27, 2021 at 6:22
  • if you are loading image locally then you should use import image from "img/path"; & <Image src={image} alt="something" Commented Jun 27, 2021 at 6:26
  • no bro I m using API call for that...if the image was coming from locally that was so much easy. Commented Jun 27, 2021 at 6:44
  • adding a width and height props will solved it. you may also want to add layout. Commented Jun 27, 2021 at 6:56
  • if it is from remote api call then why are you using /images/? in your remote api response it should be a cdn link which will have a url. so it sould be <Image src={url} /> something like this. Commented Jun 27, 2021 at 9:44

5 Answers 5

15

The issue is next/image's Image is expecting rather complex type ImageProps as it's props:

type StringImageProps = { src: string } & ( | { width?: never; height?: never; layout: 'fill' } | { width: number | string height: number | string layout?: Exclude<LayoutValue, 'fill'> } ) & ( | { placeholder?: Exclude<PlaceholderValue, 'blur'> blurDataURL?: never } | { placeholder: 'blur'; blurDataURL: string } ) type ObjectImageProps = { src: StaticImport width?: number | string height?: number | string layout?: LayoutValue placeholder?: PlaceholderValue blurDataURL?: never } export type ImageProps = Omit< JSX.IntrinsicElements['img'], 'src' | 'srcSet' | 'ref' | 'width' | 'height' | 'loading' | 'style' > & { loader?: ImageLoader quality?: number | string priority?: boolean loading?: LoadingValue unoptimized?: boolean objectFit?: ImgElementStyle['objectFit'] objectPosition?: ImgElementStyle['objectPosition'] } & (StringImageProps | ObjectImageProps) 

Since you're not importing image from local imports the only structure you're left is StringImageProps. To conform to it you have to provide one of the following props sets:

<Image src={string} layout="fill" /> // or <Image src={string} width={number} height={number} /> // with optional `layout` prop but not of type 'fill' 

both variants may be extended with optional placeholder (not of type 'blur') or required placeholder: 'blur' and blurDataURL: string.

And only after that you may provide native image's attributes as alt.

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

Comments

8

Importing the type for ImageLoaderProps solved the issue for me.

Example:

import Image from 'next/image'; import type { ImageLoaderProps } from 'next/image'; const myLoader = ({ src, width, quality }: ImageLoaderProps) => { return `https://example.com/?${src}?w=${width}&q=${quality}`; }; export default function TestComponent(props: Record<string, string>) { const { imageResource } = props; return ( <Image loader={myLoader} src={`/${imageResource}`} width="20%" height="20%" /> ); } 

Comments

1

For people that still have this issue, I had similar issue and I was using

<Image src={'image' as string} alt='Pic' /> 

You can try to import the StaticImageData type from "next/image"

Example:

import Image, {StaticImageData} from "next/image"; import image from "./pathImage" ... <Image src = {image as StaticImageData}/> 

Comments

-1

I omitted placeholder, blurDataURL and layout. I also made explicity src as string. More info on this issue: https://github.com/vercel/next.js/issues/26735

Comments

-2

Just cast string as a any

<Image src={'string' as any} alt='Pic' /> 

2 Comments

I think the assumption is when a question around TypeScript is posed, OP is aware that casting as any is an option, but is looking for a strongly typed solution.
Well, it's true that casting solves the problem very easily <Image src={imgURL as string} alt={imgName as string} />

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.