Typescript Box 生成的联合类型过于复杂而无法表示

问题描述 投票:0回答:3

渲染

Box
会产生以下错误:

表达式产生的联合类型太复杂而无法表示.ts(2590)

正如我在here所看到的,这是因为同时安装了

@mui/material
@react-three/drei
@react-three/fiber

此错误背后的原因是什么?我只从

Box
导入
mui
组件。是否存在类型混淆或其他问题?解决方案/解决方法是什么?

重现步骤:

  1. 设置 cra 应用程序:
    npx create-react-app my-app --template typescript
  2. 将以下软件包添加到您的
    package.json
  "dependencies": {
    "@azure/msal-browser": "^2.18.0",
    "@azure/msal-react": "^1.1.0",
    "@emotion/react": "^11.5.0",
    "@emotion/styled": "^11.3.0",
    "@mui/icons-material": "^5.0.4",
    "@mui/lab": "^5.0.0-alpha.51",
    "@mui/material": "^5.0.4",
    "@mui/system": "^5.0.4",
    "@react-three/drei": "^7.16.8",
    "@react-three/fiber": "^7.0.17",
    "axios": "^0.23.0",
    "dotenv": "^10.0.0",
    "localforage": "^1.10.0",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-router": "^5.2.1",
    "react-router-dom": "^5.3.0",
    "react-scripts": "4.0.3",
    "three": "^0.133.1",
    "three-stdlib": "^2.5.4",
    "web-vitals": "^1.1.2",
    "zustand": "^3.5.14"
  },
  "devDependencies": {
    "@testing-library/jest-dom": "^5.14.1",
    "@testing-library/react": "^11.2.7",
    "@testing-library/user-event": "^12.8.3",
    "@types/jest": "^26.0.24",
    "@types/node": "^12.20.33",
    "@types/react": "^17.0.30",
    "@types/react-dom": "^17.0.9",
    "@types/react-router-dom": "^5.3.1",
    "@types/three": "^0.133.1",
    "@typescript-eslint/eslint-plugin": "^4.29.3",
    "@typescript-eslint/parser": "^4.29.3",
    "cross-env": "^7.0.3",
    "eslint-config-airbnb": "^18.2.1",
    "eslint-config-airbnb-typescript": "^14.0.1",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-import": "^2.25.2",
    "eslint-plugin-jsx-a11y": "^6.4.1",
    "eslint-plugin-react": "^7.26.1",
    "eslint-plugin-react-hooks": "^4.2.0",
    "jest-when": "^3.4.1",
    "rimraf": "^3.0.2",
    "typescript": "^4.4.4"
  },
  1. 奔跑
    npm install
  2. 确保您正在运行
    Typescript v4.4.4
  3. 将以下组件添加到您的
    src
    。我把它命名为
    ThreeRenderer.tsx
import { Html, OrbitControls, PerspectiveCamera, useGLTF, useProgress } from '@react-three/drei';
import { Canvas, useFrame } from '@react-three/fiber';
import { FC, Suspense, useEffect, useRef, useState } from 'react';
import { AnimationAction, AnimationMixer } from 'three';
import { GLTF, GLTFLoader } from 'three-stdlib';
import create from 'zustand';
import { devtools } from 'zustand/middleware';

export const useGLTFModel = create<{ readonly model: () => GLTF | undefined }>(
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  devtools((set) => ({
    model: () => undefined
  }))
);

export const useGLTFAnimationAction = create<{ readonly animationAction: () => AnimationAction[] | undefined }>(
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  devtools((set) => ({
    animationAction: () => undefined
  }))
);

interface ModelProps {
  readonly gltfPath: string;
  readonly onLoad: () => void;
}

const Model: FC<ModelProps> = ({ gltfPath, onLoad }) => {
  const model = useGLTF(gltfPath, undefined, undefined, (loader: GLTFLoader) => {
    loader.manager.onLoad = onLoad;
  });

  // Refs
  const rootRef = useRef();
  const animationActionsRef = useRef<AnimationAction[]>();

  // Mixer
  const [mixer] = useState(() => new AnimationMixer(model.scene));
  useFrame((_state, delta) => mixer.update(delta));

  // Effects
  useEffect(() => {
    useGLTFModel.setState({ model: () => model });

    animationActionsRef.current = model.animations.map((animation) => mixer.clipAction(animation, rootRef.current));
    useGLTFAnimationAction.setState({ animationAction: () => animationActionsRef.current });

    return () => {
      model.animations.map((animation) => mixer.uncacheClip(animation));
    };
  }, [model, mixer]);

  return <primitive ref={rootRef.current} object={model.scene} />;
};

const Progress = () => {
  const { progress } = useProgress();
  return (
    <Html center>
      <span style={{ color: 'white' }}>{progress}% loaded</span>
    </Html>
  );
};

const ThreeRenderer: FC<ModelProps> = ({ gltfPath, onLoad }): JSX.Element => {
  const cameraRef = useRef();

  return (
    <Canvas>
      <PerspectiveCamera ref={cameraRef} position={[0, 5, 5]} />
      <OrbitControls camera={cameraRef.current} />
      <ambientLight intensity={0.5} />
      <Suspense fallback={<Progress />}>
        {/* <Environment preset="city" /> */}
        <Model gltfPath={gltfPath} onLoad={onLoad} />
      </Suspense>
    </Canvas>
  );
};

export default ThreeRenderer;

  1. 转到
    App.tsx
    并添加来自
    Box
    @mui/material
    组件。
import React from 'react';
import logo from './logo.svg';
import './App.css';
import {Box} from '@mui/material';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
        <Box>

        </Box>
      </header>
    </div>
  );
}

export default App;

  1. 您应该会看到错误出现。我所看到的:

注意 请尝试在

VSCode
或您首选的编辑器中本地重现此错误。例如,我没能在
codesandbox
上重现这一点。我不知道为什么没有出现该问题。我怀疑这是因为他们使用了不同的打字稿版本。

更新

我在 MUI 和 React-3 上都提出了问题:

reactjs typescript three.js material-ui react-typescript
3个回答
7
投票
  1. 在 VS Code 中打开 JavaScript 或 TypeScript 文件。
  2. 在 VS Code 命令面板中,运行 TypeScript:
    Select  TypeScript version command
  3. 确保您已选择“使用工作区版本”。

帖子来源:FreePhoenix888

原答案:这里


4
投票

虽然我确信在某些情况下可能会出现此问题,但现在发生在我身上的原因是

npm
安装了
@chakra-ui/system
的重复版本,它定义了
forwardRef()
的类型声明.

当我跑步时

npm ls @chakra-ui/system
我可以看到我同时拥有
@chakra-ui/[email protected]
@chakra-ui/[email protected]

这可能是因为某些依赖项(例如

@chakra-ui/[email protected]
)定义了
1.9.0
的确切版本
@chakra-ui/system
,而大多数包(例如
@chakra-ui/[email protected]
)将非常开放的
>=1.0.0
定义为
peerDependencies
。从 npm v7 开始,npm 默认安装
peerDependencies

这似乎会导致 npm 为开放的 >=1.0.0 安装

最新
版本,然后分别安装特定的
1.9.0
,并且不够智能来删除重复数据。

我可以通过以下任一方式解决这个问题

  • rm package-lock.json && npm install --legacy-peer-deps
    。然而,这对 npm 安装的软件包有很大影响。

  • 或者,将

    overrides
    (需要
    npm >=8.3
    )添加到
    package.json
    以指定要安装的特定版本。

    "overrides": {
         "@chakra-ui/system": "1.9.1"
     }
    

    您可能需要在再次运行安装之前删除它来重新生成

    package-lock.json
    ,以实际强制执行此新解决方案。

    这将确保对特定包进行重复数据删除,而不是像“--legacy-peer-deps”那样更改其他不相关的包。


0
投票

我在使用

next@14
项目和以下依赖项构建
typescript@5
时遇到了此错误:

    "@emotion/react": "^11.11.3",
    "@emotion/styled": "^11.11.0",
    "@mui/material": "^5.15.9",
    "@react-three/drei": "^9.96.5",
    "@react-three/fiber": "^8.15.15",
    "three": "^0.160.1",

错误可以通过“

Box
per
Box
”来解决,帮助打字稿理解组件的通用性:

    <Box
      component={'div'} <<< this got rid of the error
      sx={{
        position: 'fixed',
        top: 2,
        left: 2,
        zIndex: 1,
      }}
    >
    ...

进一步调试后,我将打字稿版本升级到最新的稳定标签:

5.3.3
。这解决了全局错误。

© www.soinside.com 2019 - 2024. All rights reserved.