【问题标题】:Types of property 'src' are incompatible in nextjs/imagenextjs/image 中属性“src”的类型不兼容
【发布时间】:2021-09-09 20:44:08
【问题描述】:

我正在使用 react dropzone 在我的简单应用程序中上传多张图片。为了显示要删除哪种类型的图像,我使用 TypeScript 制作了一个单独的组件。但是 Next.js 图像 src 显示错误,例如 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'.

渲染文件.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;
}

我在 src 道具中的错误是什么?

【问题讨论】:

  • 你是从本地路径还是远程cdn加载图片?
  • 如果你在本地加载图片,那么你应该使用import image from "img/path"; & &lt;Image src={image} alt="something"
  • 不,兄弟,我正在为此使用 API 调用...如果图像来自本地,那就太容易了。
  • 添加 widthheight 道具将解决它。您可能还想添加layout
  • 如果它来自远程 api 调用那你为什么使用/images/?在您的远程 api 响应中,它应该是一个带有 url 的 cdn 链接。所以它应该是&lt;Image src={url} /&gt; 这样的东西。

标签: typescript next.js nextjs-image


【解决方案1】:

问题是next/imageImage 期待相当复杂的类型ImageProps,因为它是道具:

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)

由于您不是从本地导入中导入图像,因此您剩下的唯一结构是StringImageProps。为了符合它,您必须提供以下道具集之一:

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

两种变体都可以使用可选的placeholder(不是'blur'类型)或必需的placeholder: 'blur'进行扩展。blurDataURL: string

只有在此之后,您才能提供原生 image 的属性为 alt

【讨论】:

    【解决方案2】:

    我省略了placeholderblurDataURLlayout。我还明确地将src 作为字符串。有关此问题的更多信息:https://github.com/vercel/next.js/issues/26735

    【讨论】:

      【解决方案3】:

      只需将字符串转换为 any

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

      【讨论】:

      • 我认为假设是当提出有关 TypeScript 的问题时,OP 知道转换为 any 是一种选择,但正在寻找强类型的解决方案。
      猜你喜欢
      • 2021-12-06
      • 2019-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-19
      • 2018-11-21
      相关资源
      最近更新 更多