如何修复 Deno 程序中 std 模块依赖的编译器错误?

hag*_*nek 3 dependencies deno

我知道有一个问题有同样的错误,但那里的答案对我没有帮助:deno 捆绑失败。类型“ReadableStream<R>”上不存在属性“getIterator”

\n

这是完整的错误:

\n

\xe2\x9d\xaf deno run --allow-all server.ts\n检查文件:///Users/hagenek/repos/mock-backend/server.ts\n错误:TS2339 [错误]:属性\'getIterator\'类型 \'ReadableStream\' 上不存在。\nreturn res.read.getIterator();\n~~~~~~~~~~~~\nat https://deno.land/std@0.83.0/异步/pool.ts:45:23

\n

这是我的 server.ts 代码:

\n
import { Application } from "./deps.ts";\nimport router from "./routes.ts"\nconst PORT = 4000;\nconst app = new Application();\n\napp.use(router.routes()); // Pass our router as a middleware\napp.use(router.allowedMethods()); // Allow HTTP methods on router\n\nawait app.listen({ port: PORT });\nconsole.log(`Server running on PORT: ${PORT}`)\n
Run Code Online (Sandbox Code Playgroud)\n

路线.ts:

\n
import { Router } from "https://deno.land/x/oak/mod.ts";\nimport {\n    addQuote,\n    getQuotes,\n    getQuote,\n    updateQuote,\n    deleteQuote,\n} from "./controllers/controller.ts";\n\ninterface ReadableStream<R> {\n    getIterator(): any\n}\n\nconst router = new Router(); // Create Router\n\n    router\n        .get("/api/quote", getQuotes) // Get all quotes\n        .get("/api/quote/:id", getQuote) // Get one quote of quoteID: id\n        .post("/api/quote", addQuote) // Add a quote\n        .put("/api/quote/:id", updateQuote) // Update a quote\n        .delete("/api/quote/:id", deleteQuote); // Delete a quote\n    \n    export default router;\n
Run Code Online (Sandbox Code Playgroud)\n

部门ts

\n
export {\n    Application\n} from "https://deno.land/x/oak/mod.ts"\n
Run Code Online (Sandbox Code Playgroud)\n

控制器.ts

\n
interface Quote {\n    _id: { $oid: string };\n    quote: string;\n    quoteID: string;\n    author: string;\n}\n\nimport {MongoClient} from "https://deno.land/x/mongo@v0.22.0/mod.ts";\n\nconst URI = "mongodb://127.0.0.1:27017";\n\n// Mongo Connection Init\nconst client = new MongoClient();\ntry {\n    await client.connect(URI);\n    console.log("Database successfully connected");\n} catch (err) {\n    console.log(err);\n}\n\nconst db = client.database("quotesApp");\nconst quotes = db.collection<Quote>("quotes");\n\n// DESC: ADD single quote\n// METHOD: POST /api/quote\nexport const addQuote = async ({request, response,}: {\n    request: any;\n    response: any;\n}) => {\n    try {\n        // If the request has no Body, it will return a 404\n        if (!request.hasBody) {\n            response.status = 400;\n            response.body = {\n                success: false,\n                msg: "No Data",\n            };\n        } else {\n            // Otherwise, it will try to insert\n            // a quote in the DB and respond with 201\n            const body = await request.body();\n            const quote = await body.value;\n            await quotes.insertOne(quote);\n            response.status = 201;\n            response.body = {\n                success: true,\n                data: quote,\n            };\n        }\n    } catch (err) {\n        response.body = {\n            success: false,\n            msg: err.toString(),\n        };\n    }\n};\n\n// DESC: GET single quote\n// METHOD: GET /api/quote/:id\nexport const getQuote = async ({\n                            params,\n                            response,\n                        }: {\n    params: { id: string };\n    response: any;\n}) => {\n    // Searches for a particular quote in the DB\n    const quote = await quotes.findOne({quoteID: params.id});\n    // If found, respond with the quote. If not, respond with a 404\n    if (quote) {\n        response.status = 200;\n        response.body = {\n            success: true,\n            data: quote,\n        };\n    } else {\n        response.status = 404;\n        response.body = {\n            success: false,\n            msg: "No quote found",\n        };\n    }\n};\n\n// DESC: GET all Quotes\n// METHOD GET /api/quote\nexport const getQuotes = async ({response}: { response: any }) => {\n    try {\n        // Find all quotes and convert them into an Array\n        const allQuotes = await quotes.find({}).toArray();\n        console.log(allQuotes);\n        if (allQuotes) {\n            response.status = 200;\n            response.body = {\n                success: true,\n                data: allQuotes,\n            };\n        } else {\n            response.status = 500;\n            response.body = {\n                success: false,\n                msg: "Internal Server Error",\n            };\n        }\n    } catch (err) {\n        response.body = {\n            success: false,\n            msg: err.toString(),\n        };\n    }\n};\n\n// DESC: UPDATE single quote\n// METHOD: PUT /api/quote/:id\nexport const updateQuote = async ({\n                               params,\n                               request,\n                               response,\n                           }: {\n    params: { id: string };\n    request: any;\n    response: any;\n}) => {\n    try {\n        // Search a quote in the DB and update with given values if found\n        const body = await request.body();\n        const inputQuote = await body.value;\n        await quotes.updateOne(\n            { quoteID: params.id },\n            { $set: { quote: inputQuote.quote, author: inputQuote.author } }\n        );\n        // Respond with the Updated Quote\n        const updatedQuote = await quotes.findOne({ quoteID: params.id });\n        response.status = 200;\n        response.body = {\n            success: true,\n            data: updatedQuote,\n        };\n    } catch (err) {\n        response.body = {\n            success: false,\n            msg: err.toString(),\n        };\n    }\n};\n\n\n// DESC: DELETE single quote\n// METHOD: DELETE /api/quote/:id\nexport const deleteQuote = async ({\n                               params,\n                               response,\n                           }: {\n    params: { id: string };\n    request: any;\n    response: any;\n}) => {\n    try {\n        // Search for the given quote and drop it from the DB\n        await quotes.deleteOne({quoteID: params.id});\n        response.status = 201;\n        response.body = {\n            success: true,\n            msg: "Product deleted",\n        };\n    } catch (err) {\n        response.body = {\n            success: false,\n            msg: err.toString(),\n        };\n    }\n};\n
Run Code Online (Sandbox Code Playgroud)\n

jse*_*ksn 5

问题

\n

您正在使用过时版本的deno.land/x/mongo(v0.22.0,其依赖项也已过时并且与 Deno\ 当前的内置类型库不一致)。

\n

解决方案

\n

使用与您正在使用的 Deno 版本兼容的模块版本。

\n

在撰写本答案时,Deno 稳定版本为 v 1.16.3,该模块的最新版本为 v 0.28.0https://deno.land/x/mongo@v0.28.0。他们看起来很兼容。

\n

解释

\n

这是模块中的编译器错误:

\n
% deno cache server.ts \nCheck file:///Users/deno/so-70169022/server.ts\nerror: TS2339 [ERROR]: Property \'getIterator\' does not exist on type \'ReadableStream<R>\'.\n  return res.readable.getIterator();\n                      ~~~~~~~~~~~\n    at https://deno.land/std@0.83.0/async/pool.ts:45:23\n
Run Code Online (Sandbox Code Playgroud)\n
\n

作为参考,这是我正在使用的 Deno 版本:

\n
% deno --version\ndeno 1.16.3 (release, x86_64-apple-darwin)\nv8 9.7.106.5\ntypescript 4.4.2\n
Run Code Online (Sandbox Code Playgroud)\n
\n

您可以看到错误发生在模块中https://deno.land/std@0.83.0/async/pool.ts(不幸的是,您无法编辑以修复问题)。请注意,它是来自std库中的模块(我将回到这一点)。

\n

这是入口点的模块图:

\n
\n

注意:为了提高可读性,我删除了输出中与有问题的模块无关的所有行

\n
\n
% deno info server.ts\nlocal: /Users/deno/so-70169022/server.ts\ntype: TypeScript\ndependencies: 134 unique (total 1.72MB)\n\nfile:///Users/deno/so-70169022/server.ts (334B)\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\xac file:///Users/deno/so-70169022/routes.ts (638B)\n  \xe2\x94\x94\xe2\x94\x80\xe2\x94\xac file:///Users/deno/so-70169022/controllers/controller.ts (4.24KB)\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\xac https://deno.land/x/mongo@v0.22.0/mod.ts (113B)\n      \xe2\x94\x94\xe2\x94\x80\xe2\x94\xac https://deno.land/x/mongo@v0.22.0/deps.ts (783B)\n        \xe2\x94\x94\xe2\x94\x80\xe2\x94\xac https://deno.land/std@0.83.0/node/_crypto/pbkdf2.ts (4.18KB)\n          \xe2\x94\x94\xe2\x94\x80\xe2\x94\xac https://deno.land/std@0.83.0/node/buffer.ts (15.46KB)\n            \xe2\x94\x94\xe2\x94\x80\xe2\x94\xac https://deno.land/std@0.83.0/node/_utils.ts (5.74KB)\n              \xe2\x94\x94\xe2\x94\x80\xe2\x94\xac https://deno.land/std@0.83.0/async/mod.ts (202B)\n                \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 https://deno.land/std@0.83.0/async/pool.ts (1.58KB)\n
Run Code Online (Sandbox Code Playgroud)\n

有问题的模块位于库中一系列嵌套导入的底部std,这些导入导致mongo/deps.tsmongo/mod.ts,它由./controllers/controller.ts(这是您可以直接编辑以解决问题的第一个模块)。

\n

现在我要暂停一下再回顾一下std模块:

\n

https://deno.land/std@0.116.0#releases它说:

\n
\n

标准库目前的标记与 Deno 版本无关。一旦库稳定下来,这种情况就会改变。

\n

要检查不同版本的标准库与 Deno CLI 的兼容性,请参阅此列表

\n
\n

这意味着每个版本std库的每个版本仅保证与特定版本的 Deno 兼容。

\n

std程序中 mongo 模块当前使用的库版本是 v 0.83.0,参考上面链接的兼容性 JSON 列表,您可以发现它映射到 Deno v1.6.3(相当旧)。

\n

此时,您最容易访问的选项是:

\n
    \n
  1. 使用与该版本的 mongo 模块兼容的 Deno 版本(使用旧版本的 Deno 可能不是最好的主意),或者

    \n
  2. \n
  3. 使用与较新版本的 Deno 兼容的 mongo 模块版本(让我们先尝试一下这个)

    \n
  4. \n
\n

让我们看看 mongo 模块的最新版本是什么:

\n

https://deno.land/x/mongo@v0.28.0/deps.ts是目前最新版本,它使用了0.111.0vstd库的 v 。

\n

让我们尝试更新程序中 mongo 模块的版本,看看是否修复了编译器错误:

\n

./controllers/controller.ts(第 8 行):

\n
% deno cache server.ts \nCheck file:///Users/deno/so-70169022/server.ts\nerror: TS2339 [ERROR]: Property \'getIterator\' does not exist on type \'ReadableStream<R>\'.\n  return res.readable.getIterator();\n                      ~~~~~~~~~~~\n    at https://deno.land/std@0.83.0/async/pool.ts:45:23\n
Run Code Online (Sandbox Code Playgroud)\n

现在让我们再次输入检查并缓存您的入口点:

\n
% deno cache server.ts\n\n
Run Code Online (Sandbox Code Playgroud)\n

这次没有编译错误!

\n