使用 Typescript 2.8 React Native - 无法重新声明块范围变量“控制台”

Posted

技术标签:

【中文标题】使用 Typescript 2.8 React Native - 无法重新声明块范围变量“控制台”【英文标题】:React Native with Typescript 2.8 - Cannot redeclare block-scoped variable 'console' 【发布时间】:2018-10-12 01:33:48 【问题描述】:

使用 Typescript 创建了一个 react-native 启动项目,该项目可以在 2 周前运行。现在,当我尝试运行该项目时,它会在打字稿编译期间出现错误。

在 tsconfig.json 中使用 skipLibraryCheck: true 可以修复错误。 但是为什么它会从 ~/.nvm 和 ./node_modules 目录中抛出错误?

错误(针对 node_modules/.bin/tsc 更新):

>  node_modules/.bin/tsc
node_modules/@types/react-native/index.d.ts(8742,11): error TS2451: Cannot redeclare block-scoped variable 'console'.
node_modules/@types/react-native/index.d.ts(8750,18): error TS2717: Subsequent property declarations must have the same type.  Property 'geolocation' must be of type 'Geolocation', but here has type 'GeolocationStatic'.
node_modules/@types/react-native/index.d.ts(8753,11): error TS2451: Cannot redeclare block-scoped variable 'navigator'.
node_modules/redux-thunk/index.d.ts(4,47): error TS2314: Generic type 'Dispatch<A, S>' requires 2 type argument(s).
node_modules/redux-thunk/index.d.ts(8,20): error TS2428: All declarations of 'Dispatch' must have identical type parameters.
node_modules/redux/index.d.ts(115,18): error TS2428: All declarations of 'Dispatch' must have identical type parameters.
node_modules/redux/index.d.ts(161,13): error TS2314: Generic type 'Dispatch<A, S>' requires 2 type argument(s).
node_modules/redux/index.d.ts(283,42): error TS2314: Generic type 'Dispatch<A, S>' requires 2 type argument(s).
node_modules/redux/index.d.ts(283,53): error TS2314: Generic type 'Dispatch<A, S>' requires 2 type argument(s).
node_modules/redux/index.d.ts(302,66): error TS2314: Generic type 'Dispatch<A, S>' requires 2 type argument(s).
node_modules/redux/index.d.ts(302,77): error TS2314: Generic type 'Dispatch<A, S>' requires 2 type argument(s).
node_modules/redux/index.d.ts(303,38): error TS2314: Generic type 'Dispatch<A, S>' requires 2 type argument(s).
node_modules/redux/index.d.ts(384,95): error TS2314: Generic type 'Dispatch<A, S>' requires 2 type argument(s).
node_modules/redux/index.d.ts(389,33): error TS2314: Generic type 'Dispatch<A, S>' requires 2 type argument(s).
node_modules/redux/index.d.ts(391,106): error TS2314: Generic type 'Dispatch<A, S>' requires 2 type argument(s).
node_modules/redux/index.d.ts(396,34): error TS2314: Generic type 'Dispatch<A, S>' requires 2 type argument(s).
node_modules/typescript/lib/lib.es6.d.ts(21612,13): error TS2451: Cannot redeclare block-scoped variable 'navigator'.
node_modules/typescript/lib/lib.es6.d.ts(21788,13): error TS2451: Cannot redeclare block-scoped variable 'console'.

项目详情:

❯ react-native info
  Environment:
  OS: macOS High Sierra 10.13.4
  Node: 9.11.1
  Yarn: 1.6.0
  npm: 6.0.0
  Watchman: 4.9.0
  Xcode: Xcode 9.2 Build version 9C40b
  android Studio: 2.3 AI-162.3934792

Packages: (wanted => installed)
  react: 16.3.1 => 16.3.1
  react-native: 0.55.3 => 0.55.3

package.json


  "name": "hello-world-rn",
  "version": "0.0.1",
  "private": true,
  "scripts": 
    "build": "npm run clean && npm run tsc --",
    "clean": "rimraf lib",
    "lint": "tslint src/**/*.ts",
    "start": "node node_modules/react-native/local-cli/cli.js start"
  ,
  "dependencies": 
    "native-base": "2.4.3",
    "react-native": "0.55.3",
    "react-redux": "5.0.7",
    "redux": "4.0.0",
    "redux-thunk": "2.2.0"
  ,
  "devDependencies": 
    "@types/jest": "22.2.3",
    "@types/react": "16.3.13",
    "@types/react-native": "0.55.8",
    "@types/react-redux": "5.0.19",
    "@types/react-test-renderer": "16.0.1",
    "babel-core": "6.26.3",
    "babel-jest": "22.4.3",
    "babel-preset-react-native": "4.0.0",
    "concurrently": "3.5.1",
    "eslint": "4.19.1",
    "jest": "22.4.3",
    "react": "16.3.1",
    "react-test-renderer": "^16.3.0-alpha.1",
    "rimraf": "2.6.2",
    "tslint": "5.9.1",
    "tslint-config-prettier": "1.12.0",
    "tslint-eslint-rules": "5.1.0",
    "tslint-react": "3.5.1",
    "typescript": "2.8.3"
  ,
  "jest": 
    "preset": "react-native",
    "testRegex": "lib/.+\\.(test|spec).js$",
    "coverageDirectory": "coverage",
    "coverageReporters": [
      "text-summary",
      "html"
    ]
  ,
  "collectCoverageFrom": [
    "lib/**/*.js",
    "!lib/**/*.spec.js",
    "!lib/**/*.index.js"
  ]

tsconfig.json


  "compilerOptions": 
    "target": "es6",
    "module": "commonjs",
    "jsx": "react-native",
    "sourceMap": true,
    "outDir": "./lib",
    "strict": true,
    "types": ["react", "react-native", "jest"],
    "esModuleInterop": true,
    "skipLibCheck": false
  ,
  "compileOnSave": false,
  "exclude": ["./android/*", "./ios/*", "./lib/*", "./node_modules/*"],
  "filesGlob": ["typings/index.d.ts", "src/**/*.ts", "src/**/*.tsx"],
  "types": ["react", "react-native", "jest"]

【问题讨论】:

***.com/questions/40900791/… @Sajeetharan:这里的错误不在我的代码中。它位于 node_modules/typescript 本身内。 【参考方案1】:

我真的不能告诉你时不时发生了什么破坏了打字,我主要可以给出提示......

当您从终端调用tsc 时,它将使用全球版本的打字稿,包括其核心类型,这是您收到“.nvm”错误的地方。建议您使用本地版本 (node_modules/.bin/tsc)。 我建议您尝试添加“moduleResolution: node”。我不知道为什么,试试吧,也许它可以解决一些问题。 我不确定redux-thunk 的分型是否能与新的redux@4.x 一起工作。可能是您的错误的根源。

我通常只保留“skibLibCheck”,我们永远不知道何时编写库时考虑了旧版本的 TS,甚至没有考虑“严格”标志。

从评论中编辑

似乎 react-native 添加了他自己版本的基本 javascript 类型,因此您可以通过 lib 标志禁用 TS 禁止的类型,这样它们就不会冲突。

【讨论】:

yep, typing in redux-thunk is broken with redux@4.x :/ 谢谢。我也将 moduleResolution 设置为 node 。没有skipLibCheck 仍然无法工作。即使我运行 node_modules/.bin/tsc 也会在 typescript 中出现错误。相应地更新了输出。 我注意到“react-native”似乎在重新声明基本的 es6 类型(我从未使用过 react-native)。如果 react-native 应该声明 es6 类型而不是 TS 默认类型,那么您可以在 tsconfig 上声明“lib:[]”或“noLib”,这样就不会加载默认类型。 @types/redux-thunk 可能会打破想法,您可以尝试将其删除。无论如何,它从来没有多大用处,它只是声明了一个 Dispatch&lt;any&gt; 擦除所有减速器信息(状态和操作类型)......我最近一直在手动修补调度程序(这是一个 hack)github.com/wkrueger/redutser/blob/master/type-helpers.d.ts @wkrueger 你能用你在评论中提到的选项更新你的答案吗?对我来说,指定"lib": ["ES6"] 修复了它。谢谢!【参考方案2】:

我遇到了“必须是'地理位置'类型”的问题。还在琢磨到底怎么修,但是在@types/react-native中,Geolocation被定义为GeolocationStatic的别名,但是Geolocation也是typescript类型,需要是typescript类型,而不是@types /react-native 类型。看起来@types/react-native/index.d.ts 中唯一使用 Geolocation 别名的地方是

interface Navigator 
    readonly product: string;
    readonly geolocation: Geolocation;

地理位置已分配

export var Geolocation: GeolocationStatic;
export type Geolocation = GeolocationStatic;

在运行 npm install 后将这些人评论出来,这样它就可以工作了。我把它放在一个 npm postinstall powershell 脚本中。

是的,是的,它很老套,而且我很肯定有一个平稳、良好的解决方案。但是,如果您只希望它工作并且不依赖于其他地方的这些,它可以工作。另一个可能的解决方案是重命名它们。

做了一些更多的窥探,看起来这是目前的官方推荐。一定要喜欢hacky修复! https://github.com/DefinitelyTyped/DefinitelyTyped/issues/24573

【讨论】:

【参考方案3】:

如果其他人在使用react-nativereact-native-typescript-transformer 时偶然发现这个问题:

使用react-native-typescript-transformernoEmit 时也会遇到同样的问题,因为react-native/index.d.ts 的全局类型声明与typescript/lib/lib.es6.d.ts 冲突

来自issue on github:

...使用 lib 选项定义 ES6 基本类型似乎足以解决此问题...

...导致此行为的 react-native-typescript-transformer 所需的 noEmit 选项。

解决方案

在 tsconfig.json 中指定要包含在编译中的有效库文件。 React Native 构建在 ES6 之上,这样就足够了:"lib": [ "es6" ] 在您的 package.json 中。

【讨论】:

【参考方案4】:

我在使用 react-native 和带有 nvm 的 typescript 时遇到了同样的问题。

但最终通过将 "lib": ["ES6"] 添加到我的 tsconfig.json 文件中解决了这个问题。

【讨论】:

欢迎来到 ***。请详细解释为什么添加该行有助于解决问题,或将当前行添加为评论(您现在不能,因为您的分数)。所以,请按照我的第一个建议。

以上是关于使用 Typescript 2.8 React Native - 无法重新声明块范围变量“控制台”的主要内容,如果未能解决你的问题,请参考以下文章

使用 TypeScript 在 React Native 上传递 refs:(属性) React.MutableRefObject<null>.current: null Object i

React - 类构造函数错误中的 Typescript 默认值

Springboot + mybatis + React+redux+React-router+antd+Typescript: 上线

深入浅出TypeScript- 在React项目中使用TypeScript

使用 Typescript 创建 React 组件

对 React 中如何使用接口(TypeScript)感到困惑