【问题标题】:Cannot access object property. Typescript with multer无法访问对象属性。带 multer 的打字稿
【发布时间】:2022-01-05 18:23:03
【问题描述】:

我面临一个问题,或缺乏技能的问题是:

我正在尝试将图像上传到我的应用程序并尝试将其存储在 AWS S3 中。 Bucket 和 IAM 用户已成功创建,我可以将工件存储在那里,但是当我尝试在我的数据库中保存“文件”对象的某些属性时,就会出现此问题。

我可以使用 Object.keys(requestedFile) 或 JSON.stringify(requestedFile) 在“console.log,console.info”中读取此属性。但是 VSCode 智能感知无法读取,一切都变红了,这段代码无法编译等等……

让我展示一下,并试着解释一下我是怎么做的:

这是我调用来执行此服务的路线:

routes.post("/test/upload", multerConfig.single('file'), createAttachment.handle);

multerConfig.ts

import multer from "multer";
import { limits } from "./FileLimits";
import { dest } from "./LocalDestination";
import { storageTypes } from "./StorageTypes";

export const multerConfig = multer({
    storage: storageTypes["s3"],
    dest: dest,
    limits: limits,  
});

./storageTypes.ts

import multer from "multer";
import path from "path";
import crypto from "crypto";
import multerS3 from "multer-s3"
import aws from "aws-sdk";

const fileResolvePath = __dirname +  "../../tmp/uploads";
const dest = path.resolve(fileResolvePath)

// Here I've placed local and S3 storage types, local is only for dev purposes.

export const storageTypes = {
    local: multer.diskStorage({
        destination: (req, file, cb) => {
            cb(null, dest)
        },
        filename: (req, file, cb) => {
            crypto.randomBytes(16, (err, hash) => {
                if(err) {
                    cb(err, err.message)
                } else {
                const fileName = `${hash.toString('hex')}-${file.originalname}`;
                cb(null, fileName);
                }
            })}
    }),
    s3 : multerS3({
        s3: new aws.S3(),
        bucket: "bucket-name", 
        contentType: multerS3.AUTO_CONTENT_TYPE,
        acl: 'public-read',
        key:  (req, file, cb) => {
            crypto.randomBytes(16, (err, hash) => {
                if(err){
                    cb(err, err.message)
                }else{
                    const fileName = `${hash.toString('hex')}-${file.originalname}`;
                    return cb(null, fileName);
                }
            })
        }})
        
}

好的,现在每当我尝试访问一些 req.file 属性时,所有其他属性(已添加到此对象)都无法访问。

console.log(req.file):

{
  "fieldname": "file",
  "originalname": "profile_03.PNG",
  "encoding": "7bit",
  "mimetype": "image/png",
  "size": 158935,
  "bucket": "bucket-name",
  "key": "17378cbe3e20f6ceabe274af8ca5d96e-profile_03.PNG",
  "acl": "public-read",
  "contentType": "image/png",
  "contentDisposition": null,
  "contentEncoding": null,
  "storageClass": "STANDARD",
  "serverSideEncryption": null,
  "metadata": null,
  "location": "https://bucket-name.s3.amazonaws.com/17378cb123uns1be274af8ca5d96e-perfil_03.PNG",
  "etag": "\"4fd89662891jsdu38jsdjnqr9cd\"",
  "versionId": "_tB2adfWDF49s2Fijfaoi3sW5"
}

Object.Keys(requestedFile) 的输出:

ObjectKeys: {
    objectKeys: [
      'fieldname',            'originalname',
      'encoding',             'mimetype',
      'size',                 'bucket',
      'key',                  'acl',
      'contentType',          'contentDisposition',
      'contentEncoding',      'storageClass',
      'serverSideEncryption', 'metadata',
      'location',             'etag',
      'versionId'
    ]
  },

这是我的控制器/服务类:

export class CreateAttachmentController {
    async handle ( req: Request, res: Response ){
        try {
            const {
                // this is where I try to access .key, or .location properties.
            } = req.file;
        const attachmentRepository = getCustomRepository(AttachmentRepository);
        const attachment = await attachmentRepository.create({
            // this is where I try to save this to database
        });

        await attachmentRepository.save(attachment);

        return res.json(attachment);
    }
}};

结论,我不知道我是否做错了什么,是否应该使用 Promises,或者这是预期的行为,并且在此代码中无法正常工作。顺便说一下tsconfig.json:

{
    "target": "es5",
    "module": "commonjs",
    "strict": false,
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true   
}

嗯,这就是我现在得到的一切,如果有人发现发生了什么,我将不胜感激。

提前致谢,

杜鹃

【问题讨论】:

    标签: typescript postgresql typeorm multer multer-s3


    【解决方案1】:

    经过几个小时的研究,我发现 multer-s3 并没有为 VsCode 提供原生支持类型,这使得 Visual Studio intellisense 可以看到该对象内部的内容。

    这就是我所做的:

    创建了一个导出的接口:

    import express from "express";
    
    export interface IMulterRequestFile {
        key: string
        path: string
        mimetype: string
        originalname: string
        size: number
        location: string
      }
    

    然后,进入我的Controller.ts

    export class Controller {
        async handle (req: Request & { file: MulterFile }, res: Response){ 
    }
    

    然后,现在我正在访问我想要访问的所有属性,multer-S3 已插入到文件对象中。实际上,这不是一种优雅的方式,但它确实有效! (:

    ps:我不知道他们将来是否会提出 PR 来解决这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-16
      • 2019-10-27
      • 1970-01-01
      • 2011-07-05
      相关资源
      最近更新 更多