NPM 包不能用作 JSX 组件 - 类型错误

NPM package cannot be used as a JSX Component - Type errors

我的 typescript 项目中某些包出现了这些奇怪的类型错误。 例如:

'TimeAgo' cannot be used as a JSX component.
  Its instance type 'ReactTimeago<keyof IntrinsicElements | ComponentType<{}>>' is not a valid JSX element.
    The types returned by 'render()' are incompatible between these types.
      Type 'React.ReactNode' is not assignable to type 'import("/home/user/app/node_modules/@types/react-bootstrap-table-next/node_modules/@types/react/index").ReactNode'.
        Type '{}' is not assignable to type 'ReactNode'.

我在本地 windows 机器上没有遇到这些类型错误,但它们在我的 linux 虚拟机中不断出现。我已经多次删除项目,克隆我的 repo 并在不同版本的节点中再次安装包,但我仍然遇到相同类型的错误。

已检查节点 12.18.3、16.13.1

这是一些快捷包json信息:

"react-timeago": "^6.2.1",
"react-custom-scrollbars": "^4.2.1",
"react-custom-scrollbars-2": "^4.4.0",
"react": "^17.0.2",
"next": "^12.1.1",
"@types/react-custom-scrollbars": "^4.0.10",
"@types/react-timeago": "^4.1.3",
"@types/react": "^17.0.44",
"typescript": "^4.3.5"
"@types/node": "^14.18.12",

这发生在基本的自定义组件上:

MyTst.tsx
import TimeAgo from "react-timeago";

const Mytst = () => {
  return (
    <div>
      <TimeAgo date={"02/02/2022"} />
    </div>
  );
};

export default Mytst;

对于 react-custom-scrollbars-2 我也遇到了这个错误。在包含组件的库和与其关联的@types 文件之间正确匹配类型似乎存在问题。有人对如何解决这些类型错误有任何想法吗?

我知道今天发布

rm -rf node_modules
rm -rf yarn.lock
npm install

刚刚使用 npm install 解决了问题 但我不知道发生了什么

好的。我最终解决了这个问题,但提前警告你,没有什么神奇的方法可以做到这一点。

我基本上卸载了所有我认为是罪犯的@types。您可以通过阅读您的错误 window 来找出这一点。关键是我上面的原始错误中的这条消息。

Type 'React.ReactNode' is not assignable to type 'import("/home/user/app/node_modules/@types/react-bootstrap-table-next/node_modules/@types/react/index").ReactNode'.

如果您看到节点模块类型指向的位置并且它与您的库无关,请将其删除。就我而言,我的问题是包 TimeAgo,类型错误显示类型已分配给不同的包。所以我卸载了它并不断循环检查错误,直到它消失。

然后我使用 npm 运行 build 进行类型检查并指示我必须重新安装哪些类型。 (可能有更好的方法来完成这部分,但它对我有用,尽管它很乏味。)

这个问题似乎发生在当你有大量不同的库和它们的类型有相似的依赖关系和超时时,如果它们不需要,不要做我做的,只是让它们堆积在你的 package.json.

因此,如果您认为任何类型都可能与您的库发生冲突,请卸载并查看错误是否消失,如果出现其他类型错误表明缺少 dev 类型包,则重新安装。我还有一些 @type 包作为依赖项而不是 devDependencies,我将其删除并移回 dev。不知道有没有影响。

如有疑问,请删除所有适用的类型并查看问题是否已解决。

有同样的问题。 只需添加这个

"resolutions": {
  "@types/react": "17.0.2",
  "@types/react-dom": "17.0.2"
},

package.json文件和运行yarn命令。

更新: 稍微详细一点的回答:

@types/react-dom 有自己的依赖项,其中之一是 @types/react,版本设置为 '*' - 一个主要版本,现在可能指的是 18.

即使您在 package.json 中指定了一些严格的版本(没有 ^),父包也可能会安装您已经用于其自身目的的包的副本。

通过使用resolutions,我们对依赖项的依赖项指定了严格的限制。

我也有同样的问题,所以我更新了 npm 版本 ^6.0.0 -> 8.0.0 并解决了。

检查 npm 版本。

如果您的 npm 版本较旧,只需将 npm 更新到版本 > 8.0.0。 它对我有用。

我有 npm 版本 6.x.x。我尝试了很多解决方案,但是将 npm 更新到新版本很容易解决这个问题。

对于 npm!

检查您安装的节点和 npm 版本。 如果你更新到 8.x,npm 会为你提供与 resolution 为 yarn 提供的相同的东西,但它会“覆盖”。 像这样更新您的包裹:

"overrides": {
  "@types/react": "17.x.x",
  "@types/react-dom": "17.x.x"
}

我的 npm 和节点版本在本地实例上是最新的,但在 git ci 上不是。更新后,它可以在不覆盖 react 和 react-dom.

版本的情况下工作

您需要修复 @types/react 包的版本,因为许多 React 库的依赖项设置为 @types/react : "*",这将采用最新版本的包。 (我想他们刚刚发布了第 18 版)

为此,您可以将此添加到 package.json

"resolutions": {
  "@types/react": "^17.0.38"
}

它在 yarn 上工作得很好,但如果你使用 npm,那么你还需要在 package.json

的“脚本”部分添加它
"preinstall": "npm install --package-lock-only --ignore-scripts && npx npm-force-resolutions"

这将简单地使用 npm-force-resolutions 包来修复决议中的版本。

然后在执行 npm install 之后,您的应用应该可以正常运行。

我发布了一个不同的答案,但它基本上是一个重复的答案,所以我将提供另一种方法。

如果您使用的是 yarn,您可以 运行 yarn dedupe,它将对您的 yarn.lock 文件进行必要的更改。它将合并对同一包的任何引用以解析为正确的版本。从这里可以看出,- 行是被删除的,+ 行被修改并保存:

-"@types/react@npm:*, @types/react@npm:>=15, @types/react@npm:>=16.9.0":
-  version: 17.0.43
-  resolution: "@types/react@npm:17.0.43"
-  dependencies:
-    "@types/prop-types": "*"
-    "@types/scheduler": "*"
-    csstype: ^3.0.2
-  checksum: 981b0993f5b3ea9d3488b8cc883201e8ae47ba7732929f788f450a79fd72829e658080d5084e67caa008e58d989b0abc1d5f36ff0a1cda09315ea3a3c0c9dc11
-  languageName: node
-  linkType: hard
-
-"@types/react@npm:^18.0.0":
+"@types/react@npm:*, @types/react@npm:>=15, @types/react@npm:>=16.9.0, @types/react@npm:^18.0.0":
"@types/react@npm:*, @types/react@npm:>=15, @types/react@npm:>=16.9.0"

合并为

"@types/react@npm:*, @types/react@npm:>=15, @types/react@npm:>=16.9.0, @types/react@npm:^18.0.0"

有样式组件。决议对我不起作用所以这是另一个 解决方案:

暴力类型铸造:

const ThemeProviderFixed = ThemeProvider as unknown as React.FC<PropsWithChildren<{ theme: string }>>;

我最近在升级到 React 18 时遇到了这个问题,忘记升级我在 devDependencies 中的相应类型。

对我有用的是升级 React 类型以在 package.json 文件中匹配,如图所示

{
    ...
    "dependencies": {
        ...
        "react": "^18.1.0",
    },
    "devDependencies": {
        ...
        "@types/react": "^18.0.8",
    }
}

不幸的是,在我的情况下,我无法使用投票最多的答案,因为我 需要 @types18 因为我需要使用 react@18 中的最新钩子,例如 useId 并且我无法使用 @types/react@17 导入它们,因为它们没有用于这些挂钩的导出成员。 感谢@Chris Web 的回答,我能够使用最新的类型来修复损坏的类型化 deps。例如,对于 Redux 提供商:

// temp fix due to @types/react@18
const Provider = _Provider as unknown as React.FC<{
  children?: JSX.Element | string;
  store: any;
}>;

store: any 并不理想,但这只是临时修复。