繁体   English   中英

使用 require 时出现打字稿错误 - 此表达式不可调用。 类型“typeof import(...)”没有调用签名.ts(2349)

[英]Typescript error when using require - This expression is not callable. Type 'typeof import(...)' has no call signatures.ts(2349)

我正在尝试运行此脚本

const fetch = require('node-fetch');

function test() {
  fetch('https://google.com')
    .then(res => res.text())
    .then(text => console.log(text))
}

test();

但我得到这个错误

此表达式不可调用。 类型 'typeof import("(...)/node_modules/node-fetch/@types/index")' 没有调用 signatures.ts(2349)

虽然它在我使用导入时有效

import fetch from 'node-fetch';

为什么以及如何解决它?

您有以下选择:

  1. 自己使用 ESM。 (首选)
    使用import foo from 'node-fetch'而不是const fetch = require('node-fetch')来导入包。 您还需要将"type": "module"放在 package.json 等中。 请按照以下指南进行操作。
  2. 如果包在异步上下文中使用,您可以使用来自 CommonJS 的await import(…)而不是require(…)
  3. 继续使用现有的 2.x 版本的 node-fetch,直到您可以移动到 ESM。

我强烈建议转向 ESM。 ESM 仍然可以导入 CommonJS 包,但是 CommonJS 包无法同步导入 ESM 包。

Node.js 12 及更高版本原生支持 ESM。

如何将我的 CommonJS 项目转移到 ESM?

  • "type": "module"到您的 package.json。
  • 将 package.json 中的"engines"字段更新为 Node.js 12: "node": ">=12.20.0"
  • 删除'use strict'; 来自所有 JavaScript 文件。
  • 将所有require() / module.exportimport / export
  • 仅使用完整的相对文件路径进行导入: import x from '.'; import x from './index.js'; .
  • 如果您有 TypeScript 类型定义(例如, index.d.ts ),请将其更新为使用 ESM 导入/导出。
  • 可选但推荐使用node:协议进行导入。

我可以在我的 TypeScript 项目中导入 ESM 包吗?

是的,但您需要将您的项目转换为输出 ESM。 见下文。

如何使我的 TypeScript 项目输出 ESM?

  • "type": "module"到您的 package.json。
  • 将 package.json 中的"main": "index.js"替换为"exports": "./index.js"
  • 将 package.json 中的"engines"字段更新为 Node.js 12: "node": ">=12.20.0"
  • "module": "ES2020"到您的 tsconfig.json。
  • 仅使用完整的相对文件路径进行导入: import x from '.'; import x from './index.js'; .
  • 删除namespace使用并改用export
  • 可选但推荐使用node:协议进行导入。
  • 即使您正在导入.ts文件,您也必须在相对导入中使用.js扩展名。

如果您使用ts-node ,请遵循本指南

如何导入 JSON?

JavaScript 模块最终将获得对 JSON 的原生支持,但现在,您可以这样做:

import {promises as fs} from 'node:fs';
const packageJson = JSON.parse(await fs.readFile('package.json'));

如果你的目标是 Node.js 14 或更高版本,你可以使用import fs from 'node:fs/promises';导入它import fs from 'node:fs/promises'; 反而。

根据spender评论,您可以更改使用此解构的要求:

const {default : fetch} = require('node-fetch');

这在类似的情况下对我有用(在节点中使用 axios,它具有类似的 API)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM