TypeScript报错:ReadableStream类型不存在pipe属性的问题求助
解决TypeScript中ReadableStream无pipe方法的问题
报错原因
fetch返回的res.body是Web标准的ReadableStream,而Node.js的fs.createWriteStream生成的是Node.js原生WritableStream,两者API不兼容——Web Stream没有pipe方法,pipeThrough/pipeTo也只能对接Web标准的流,无法直接和Node.js Stream配合。
解决方案
方法1:转换Web Stream为Node.js Stream(Node.js 18+)
利用Node.js内置的stream/web模块,将Web ReadableStream转换为Node.js原生Readable,即可使用pipe方法:
import { createWriteStream } from 'fs'; import { Readable } from 'stream/web'; // Node.js 18+内置fetch,低于18版本需安装node-fetch并导入 fetch("https://raw.githubusercontent.com/Fizzify/dotfiles/main/wallpaper.jpg") .then(async (res: Response) => { const dest = createWriteStream("./Doom.png"); // 转换Web流为Node.js可读流 const nodeReadable = Readable.fromWeb(res.body!); nodeReadable.pipe(dest); return new Promise((resolve, reject) => { nodeReadable.on("end", () => resolve("it worked")); dest.on("error", reject); nodeReadable.on("error", reject); }); }) .then(() => console.log("Done downloading!")) .catch(err => console.error("下载失败:", err));
方法2:改用Node.js原生https模块(解决0KB空文件问题)
之前用https模块下载得到空文件,是因为未正确处理流事件或错误。以下是正确实现:
import { createWriteStream } from 'fs'; import https from 'https'; https.get("https://raw.githubusercontent.com/Fizzify/dotfiles/main/wallpaper.jpg", (res) => { const dest = createWriteStream("./Doom.png"); res.pipe(dest); // 流写入完成时关闭文件 dest.on('finish', () => { dest.close(); console.log("Done downloading!"); }); // 捕获请求和写入过程中的错误 res.on('error', (err) => { console.error("请求错误:", err); dest.destroy(); }); dest.on('error', (err) => { console.error("写入错误:", err); dest.destroy(); }); }).on('error', (err) => { console.error("HTTPS请求失败:", err); });
方法3:使用Web Stream的pipeTo配合FileHandle
如果偏好Web API风格,可通过fs/promises的FileHandle创建兼容Web Stream的可写流:
import { open } from 'fs/promises'; fetch("https://raw.githubusercontent.com/Fizzify/dotfiles/main/wallpaper.jpg") .then(async (res: Response) => { const fileHandle = await open("./Doom.png", 'w'); // 直接用Web Stream的pipeTo方法 await res.body!.pipeTo(fileHandle.createWriteStream()); await fileHandle.close(); return "it worked"; }) .then(() => console.log("Done downloading!")) .catch(err => console.error("下载失败:", err));
内容的提问来源于stack exchange,提问作者Fizzify
相关产品推荐
相关产品推荐

