求基于AWS SDK for S3的TypeScript示例:实现MP3文件上传与下载
Got it, let's fix that TypeScript compilation issue you hit with the JavaScript example and get your MP3 file operations working smoothly with AWS S3. Below is a complete, type-safe implementation using the AWS SDK for JavaScript v3—it has first-class TypeScript support, unlike the older v2 SDK which often causes type errors without extra setup.
Step 1: Install Dependencies
First, install the required packages. We'll use the modular v3 SDK for better tree-shaking and built-in types, plus dotenv to manage sensitive credentials:
npm install @aws-sdk/client-s3 @aws-sdk/lib-storage dotenv npm install -D typescript @types/node
Step 2: Configure AWS Credentials
Create a .env file in your project root to store your AWS details (never commit this file to version control!):
AWS_ACCESS_KEY_ID=your-access-key-here AWS_SECRET_ACCESS_KEY=your-secret-key-here AWS_REGION=your-region (e.g., us-east-1) S3_BUCKET_NAME=your-bucket-name-here
Step 3: Full TypeScript Code Implementation
Create a file like s3-mp3-handler.ts with the following code:
Initialize S3 Client
First, set up the S3 client with your credentials and region, with proper type assertions:
import { S3Client } from "@aws-sdk/client-s3"; import dotenv from "dotenv"; dotenv.config(); const s3Client = new S3Client({ region: process.env.AWS_REGION, credentials: { accessKeyId: process.env.AWS_ACCESS_KEY_ID as string, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY as string, }, });
Upload MP3 to S3
We'll use the Upload utility from @aws-sdk/lib-storage to handle large MP3 files with multi-part upload (it automatically retries failed parts and supports resumable uploads):
import { Upload } from "@aws-sdk/lib-storage"; import { createReadStream } from "fs"; import { join } from "path"; /** * Upload an MP3 file to AWS S3 * @param localFilePath Path to the local MP3 file * @param s3Key The filename/key to use in the S3 bucket * @returns Promise with the upload result */ async function uploadMp3ToS3(localFilePath: string, s3Key: string) { try { const uploadParams = { Bucket: process.env.S3_BUCKET_NAME as string, Key: s3Key, Body: createReadStream(join(process.cwd(), localFilePath)), ContentType: "audio/mpeg", // Critical for correct MIME type handling }; const upload = new Upload({ client: s3Client, params: uploadParams, }); // Optional: Track upload progress upload.on("httpUploadProgress", (progress) => { console.log(`Upload progress: ${Math.round((progress.loaded / progress.total) * 100)}%`); }); const result = await upload.done(); console.log("MP3 uploaded successfully:", result.Location); return result; } catch (err) { console.error("Error uploading MP3:", err); throw err; } }
Download MP3 from S3
Retrieve an MP3 file from S3 and save it to your local filesystem using streams (efficient for large files):
import { GetObjectCommand } from "@aws-sdk/client-s3"; import { createWriteStream } from "fs"; import { pipeline } from "stream/promises"; /** * Download an MP3 file from AWS S3 to local filesystem * @param s3Key The filename/key of the MP3 in S3 * @param localOutputPath Path to save the downloaded MP3 * @returns Promise that resolves when download is complete */ async function downloadMp3FromS3(s3Key: string, localOutputPath: string) { try { const command = new GetObjectCommand({ Bucket: process.env.S3_BUCKET_NAME as string, Key: s3Key, }); const response = await s3Client.send(command); // Use stream pipeline to handle large files without memory issues await pipeline(response.Body as NodeJS.ReadableStream, createWriteStream(localOutputPath)); console.log(`MP3 downloaded successfully to ${localOutputPath}`); } catch (err) { console.error("Error downloading MP3:", err); throw err; } }
Usage Example
Test the functions with your own MP3 files:
// Example: Upload a local MP3 uploadMp3ToS3("path/to/your/local/track.mp3", "my-audio-collection/track1.mp3") .then(() => { // Example: Download the same MP3 back to local return downloadMp3FromS3("my-audio-collection/track1.mp3", "path/to/save/downloaded-track.mp3"); }) .catch((err) => console.error("Operation failed:", err));
Why the Original JavaScript Example Failed in TypeScript
The example you referenced uses the AWS SDK v2, which doesn't include native TypeScript types. Even if you installed @types/aws-sdk to add types, you'd still run into issues with untyped callbacks and implicit any types that TypeScript's strict mode rejects. The v3 SDK we used here is built for TypeScript from the ground up, with strict type definitions for all commands and parameters.
内容的提问来源于stack exchange,提问作者Southsouth

