我已经写了一个代码,应该验证和转换通过它的每个图像。我使用了nestjs, magic-bytes.js和Sharp。但是我得到一个错误,说:
类型'Promise
[]'缺少以下属性输入'Promise ':然后,catch,最后,(Symbol.toStringTag) ts (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.log(`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;
}
}
我已经尝试通过compressedFiles删除类型,但随后我得到了另一个错误,说:
类型'Promise
[]'不能赋值给类型'File |文件[]'
Buffer
不等于Express.Multer.File
。由于files.map
,您的compressedFiles
常数为Buffer[]
类型。你可能想要做的事情是
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()
}),
));
请注意,你不能在Array.prototype.map
方法中使用async
,如果你确实需要使用async,你应该像我在上面所做的那样在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.log(newFile);
return newFile;
}),
);
return Array.isArray(incomingFiles) ? compressedFiles : compressedFiles[0];
}
}