10

我的目标是构建一个带有 AJAX 调用的Typescript库(通过使用fetch API),客户端(Webpack/Browserify)后端开发人员(Node)都可以使用它。

但是,我似乎无法在fetch没有错误的情况下编译。


我的第一次尝试是使用isomorphic-fetchand @types/isomorphic-fetch。我不确定这些类型是否完整,但它们没有带来任何全局变量(它们应该带来 fetch,不是吗?)

npm i isomorphic-fetch @types/isomorphic-fetch

索引.ts

import 'isomorphic-fetch';
export function execute() {
  return fetch('...') ...
}

tsconfig.json

"compilerOptions": {
  ...
  "lib": ["es2015", "es2016", "es2017"]
}

输出:

node_modules/@types/isomorphic-fetch/index.d.ts(8,30): error TS2304: Cannot find name 'fetch'.
src/index.ts(4,25): error TS2304: Cannot find name 'fetch'.

我需要“ dom”吗?显然,使用domlib 它确实可以编译并在这两个 ✓ 上运行,但我无法控制它是否真的可以在 Node.js 上运行。我的意思是,无论 I 与否它都会编译import 'isomorphic-fetch',但如果我错过它,它将在 Node 上失败,恕不另行通知。

此外,Node 不是“ dom”,不管我是否也想支持浏览器。


我的第二次尝试是使用whatwg-fetch.

npm i whatwg-fetch @types/whatwg-fetch

tsconfig.json

"lib": ["es2015", "es2016", "es2017"] // The same.

这个甚至没有通过编译阶段(不管“ dom”库):

> tsc --watch

node_modules/@types/whatwg-fetch/index.d.ts(11,27): error TS2304: Cannot find name 'window'.
node_modules/@types/whatwg-fetch/index.d.ts(31,25): error TS2304: Cannot find name 'Blob'.
node_modules/@types/whatwg-fetch/index.d.ts(31,64): error TS2304: Cannot find name 'FormData'.
node_modules/@types/whatwg-fetch/index.d.ts(36,21): error TS2304: Cannot find name 'Blob'.
node_modules/@types/whatwg-fetch/index.d.ts(37,25): error TS2304: Cannot find name 'FormData'.
17:31:50 - Compilation complete. Watching for file changes.

带“ dom”:

node_modules/typescript/lib/lib.dom.d.ts(9353,11): error TS2300: Duplicate identifier 'Request'.
node_modules/typescript/lib/lib.dom.d.ts(9370,13): error TS2300: Duplicate identifier 'Request'.
node_modules/typescript/lib/lib.dom.d.ts(9375,11): error TS2300: Duplicate identifier 'Response'.
node_modules/typescript/lib/lib.dom.d.ts(9386,13): error TS2300: Duplicate identifier 'Response'.
node_modules/typescript/lib/lib.dom.d.ts(14940,18): error TS2451: Cannot redeclare block-scoped variable 'fetch'.
node_modules/typescript/lib/lib.dom.d.ts(14945,6): error TS2300: Duplicate identifier 'BodyInit'.
node_modules/typescript/lib/lib.dom.d.ts(14966,6): error TS2300: Duplicate identifier 'HeadersInit'.
node_modules/typescript/lib/lib.dom.d.ts(14976,6): error TS2300: Duplicate identifier 'RequestInfo'.
node_modules/typescript/lib/lib.dom.d.ts(15043,6): error TS2300: Duplicate identifier 'ReferrerPolicy'.
node_modules/typescript/lib/lib.dom.d.ts(15044,6): error TS2300: Duplicate identifier 'RequestCache'.
node_modules/typescript/lib/lib.dom.d.ts(15045,6): error TS2300: Duplicate identifier 'RequestCredentials'.
node_modules/typescript/lib/lib.dom.d.ts(15046,6): error TS2300: Duplicate identifier 'RequestDestination'.
node_modules/typescript/lib/lib.dom.d.ts(15047,6): error TS2300: Duplicate identifier 'RequestMode'.
node_modules/typescript/lib/lib.dom.d.ts(15048,6): error TS2300: Duplicate identifier 'RequestRedirect'.
node_modules/typescript/lib/lib.dom.d.ts(15049,6): error TS2300: Duplicate identifier 'RequestType'.
node_modules/typescript/lib/lib.dom.d.ts(15050,6): error TS2300: Duplicate identifier 'ResponseType'.
...

我也尝试过使用其他类似的库,例如fetch-ponyfill,但这个库甚至没有可用于 TypeScript 的类型。


我们应该如何调用fetch通用应用程序(浏览器 + 节点)?

谢谢!

4

3 回答 3

6

要获得正确的类型定义,您有几个选择。

如果您的 TypeScript 将在浏览器中运行

将内置的“DOM”添加到编译器库(使用命令--lib行编译器选项lib intsconfig.json)。如果您的 TypeScript 将在现代浏览器中运行,那么将“DOM”添加到库中可能是正确的选择。但是,如果您的 TypeScript 是在带有 fetch 模块的非浏览器环境中运行,请检查选项 2。

如果您的 TypeScript 将在服务器 (node.js) 上运行

如果您在节点上使用类似node-fetch的库,则添加@types/node-fetch类型定义,然后导入 fetchimport fetch from "node-fetch"

如果您的 TypeScript 在浏览器和服务器上都运行(例如,对于服务器端渲染项目),请导入 DOM 库,并且您可能想要添加isomorphic-fetch 包

于 2019-01-19T19:57:56.650 回答
4

我在一个角度(打字稿)项目中使用 fetch 时遇到了同样的错误,我可以通过像这样声明 fetch 来解决它:

  declare var fetch;
于 2017-10-24T14:44:19.587 回答
0

如果您使用以下命令进行编译:

"ts-watch": "tsc file1.ts file2.ts --watch"

然后删除单个文件声明,如果您有有效的 tsconfig.json,它应该可以工作:

"ts-watch": "tsc --watch"

这是一个有效的 tsconfig 示例:

{
  "compilerOptions": {
    "outDir": "lib",
    "sourceMap": true,
    "noImplicitAny": true,
    "lib": [
      "ES2015",
      "DOM"
    ],
    "module": "esnext",
    "target": "ES2015",
    "strict": true,
    "jsx": "react",
    "allowJs": true,
    "declaration": true,
    "moduleResolution": "node",
    "typeRoots": [
      "node_modules/@types/",
      "index.d.ts"
    ],
    "esModuleInterop": true
  },
  "include": [
    "./typescript/**/*",
  ]
}
于 2021-12-05T02:32:11.443 回答