#typescript #next.js #nextjs-image
Вопрос:
Я использую react dropzone для загрузки нескольких изображений в своем простом приложении. Для того, чтобы показать, какой тип изображений для этого подходит, я создаю отдельный компонент с машинописным текстом. Но Next.js изображение src показывает ошибку типа:
'{ src: string; alt: string; }' is not assignable to type 'IntrinsicAttributes amp; 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;
типы.ts:
export interface IFile {
name: string;
sizeInBytes: number;
formate: string | number;
id?: string;
}
В чем моя ошибка в реквизите src?
Комментарии:
1. вы загружаете изображение с локального пути или с любого удаленного cdn?
2. если вы загружаете изображение локально, вам следует использовать
import image from "img/path";
amp;<Image src={image} alt="something"
3. нет, братан, для этого я использую вызов API…если изображение поступало локально, это было так просто.
4. добавление a
width
иheight
реквизита решит эту проблему. вы также можете захотеть добавитьlayout
.5. если это из удаленного вызова api, то почему вы используете
/images/
? в вашем удаленном ответе api это должна быть ссылка cdn, которая будет содержать URL-адрес. так что это должно быть что-то вроде этого.<Image src={url} />
Ответ №1:
Проблема next/image
в том, что s Image
ожидает довольно сложный тип ImageProps
, поскольку это реквизит:
type StringImageProps = {
src: string
} amp; (
| { width?: never; height?: never; layout: 'fill' }
| {
width: number | string
height: number | string
layout?: Exclude<LayoutValue, 'fill'>
}
) amp;
(
| {
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'
> amp; {
loader?: ImageLoader
quality?: number | string
priority?: boolean
loading?: LoadingValue
unoptimized?: boolean
objectFit?: ImgElementStyle['objectFit']
objectPosition?: ImgElementStyle['objectPosition']
} amp; (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
(не типа «размытие») или обязательным placeholder: 'blur'
и. blurDataURL: string
И только после этого вы можете предоставить атрибуты native image
в качестве alt
.
Ответ №2:
Я опустил placeholder
, blurDataURL
и layout
. Я также сделал эксплицитность src
в виде строки. Более подробная информация по этому вопросу: https://github.com/vercel/next.js/issues/26735
Ответ №3:
Просто приведите строку как любую
<Image src={'string' as any} alt='Pic' />
Комментарии:
1. Я думаю, что предположение состоит в том, что, когда ставится вопрос о машинописном тексте, ОП осознает, что приведение как
any
вариант, но ищет строго типизированное решение.