Я написал код, который должен проверять и преобразовывать каждое проходящее через него изображение. Я использовал nestjs , magic-bytes.js и Sharp. Но я получаю сообщение об ошибке:
В типе «Promise<Buffer>[]» отсутствуют следующие свойства из введите «Обещание <Файл | File[]>': то поймать, наконец, [Symbol.toStringTag] тс (2739)
Может ли кто-нибудь помочь мне исправить это?
import { ArgumentMetadata, BadRequestException, Injectable, PipeTransform } from "@nestjs/common";
import { filetypemime } from "magic-bytes.js";
import * as sharp from "sharp";
@Injectable()
export class ParseFile implements PipeTransform {
async transform(
incomingFiles: Express.Multer.File | Express.Multer.File[],
metadata: ArgumentMetadata,
): Promise<Express.Multer.File | Express.Multer.File[]> {
const files = Array.isArray(incomingFiles) ? incomingFiles : [incomingFiles];
const bytes = files.map((file) => new Uint8Array(file.buffer));
const fileMimetype = filetypemime(bytes);
if (fileMimetype) {
console.info(`File type is ${fileMimetype}`);
}
if (incomingFiles === undefined || incomingFiles === null) {
throw new BadRequestException("Validation failed (file expected)");
}
if (Array.isArray(incomingFiles) && incomingFiles.length === 0) {
throw new BadRequestException("Validation failed (files expected)");
}
const compressedFiles: Promise<Express.Multer.File | Express.Multer.File[]> = files.map(
async (file) => await sharp(file.buffer).resize(320, 240).toFormat("webp").toBuffer(),
);
return Array.isArray(incomingFiles) ? compressedFiles : compressedFiles;
}
}
Я попытался удалить тип с помощью сжатых файлов, но затем я получил еще одну ошибку, которая говорит:
Тип «Promise<Buffer>[]» не может быть назначен типу «Файл | Файл[]'
Buffer
не то же самое, что Express.Multer.File
. Ваша константа compressedFiles
имеет тип Buffer[]
из-за files.map
. То, что вы, вероятно, хотите сделать, это что-то вроде
const compressedFiles: Promise<Express.Multer.File | Express.Multer.File[]> = await Promise.all(files.map(
(file) => ({
...file,
buffer: sharp(file.buffer).resize(320, 240).toFormat("webp").toBuffer()
}),
));
Обратите внимание, что вы не можете использовать async
внутри метода Array.prototype.map
, и если вам нужно использовать асинхронность, вы должны обернуть все в Promise.all
, как я сделал выше.
Я обнаружил, что это работает лучше всего для меня. Спасибо за помощь, потому что я получил много вдохновения от ответа, который я получил.
import { ArgumentMetadata, BadRequestException, Injectable, PipeTransform } from "@nestjs/common";
import { filetypemime } from "magic-bytes.js";
import * as sharp from "sharp";
import { Readable } from "stream";
import { randomUUID } from "crypto";
@Injectable()
export class ParseFile implements PipeTransform {
async transform(
incomingFiles: Express.Multer.File | Express.Multer.File[],
metadata: ArgumentMetadata,
): Promise<Express.Multer.File | Express.Multer.File[]> {
const files = Array.isArray(incomingFiles) ? incomingFiles : [incomingFiles];
const bytes = files.map((file) => new Uint8Array(file.buffer));
const mimeTypes = bytes.map((byte) => filetypemime(byte as any));
if (mimeTypes.every((type) => type.includes("image"))) {
throw new BadRequestException(
`Validation failed (file should be an image), mimetype: ${mimeTypes}`,
);
}
if (incomingFiles === undefined || incomingFiles === null) {
throw new BadRequestException("Validation failed (file expected)");
}
if (Array.isArray(incomingFiles) && incomingFiles.length === 0) {
throw new BadRequestException("Validation failed (files expected)");
}
const compressedFiles = await Promise.all(
files.map(async (file) => {
const buffer = await sharp(file.buffer).resize(320, 240).toFormat("webp").toBuffer();
const newFile: Express.Multer.File = {
fieldname: file.fieldname,
originalname: `${randomUUID()}.webp`,
encoding: file.encoding,
mimetype: "image/webp",
buffer: buffer,
size: buffer.length,
destination: "",
stream: new Readable(),
filename: "",
path: "",
};
console.info(newFile);
return newFile;
}),
);
return Array.isArray(incomingFiles) ? compressedFiles : compressedFiles[0];
}
}
Ваш ответ содержит только код. Я рекомендую вам не только опубликовать код в качестве ответа, но и предоставить объяснение того, что делает ваш код и как он решает проблему вопроса. Ответы с объяснением, как правило, более полезны и качественны, и с большей вероятностью привлекут положительные голоса. Можете ли вы отредактировать свой ответ, чтобы включить это?