React Three Fiber OBJLoader 与@types/three 冲突

React Three Fiber OBJLoader conflicts witth @types/three

我正在关注官方的 React Three Fiber 文档。我正在尝试使用这篇文章将 .obj 文件加载到我的场景中:react-three-fiber docs: loading obj models 麻烦从这里开始:

Part 1: import of OBJLoader

最好的情况,我认为这个问题可以在这里解决。

我非常乐意在这里找到并解决错误,因为它只会在以后变得更丑陋。无论如何,我似乎无法让以下行工作。请注意,这实际上是从官方文档中复制粘贴的:

import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'

这条线在 VSC 中被标记为红色,当我将鼠标悬停在它上面时,我得到了这些信息:

'OBJLoader' is declared but its value is never read.ts(6133)
Could not find a declaration file for module 'three/examples/jsm/loaders/OBJLoader'. 'F:/Documents/myproject/node_modules/three/examples/jsm/loaders/OBJLoader.js' implicitly has an 'any' type.
Try `npm i --save-dev @types/three` if it exists or add a new declaration (.d.ts) file containing `declare module 'three/examples/jsm/loaders/OBJLoader';`

尝试使用 npm run 托管项目,从此时开始,出现以下错误:

Failed to compile.
F:/Documents/myproject/src/components/editor/Editor.tsx
Type error: Could not find a declaration file for module 'three/examples/jsm/loaders/OBJLoader'. 'F:/Documents/myproject/node_modules/three/examples/jsm/loaders/OBJLoader.js' implicitly has an 'any' type.
Try `npm i --save-dev @types/three` if it exists or add a new declaration (.d.ts) file containing `declare module 'three/examples/jsm/loaders/OBJLoader';`  TS7016

Part 2: Installing @types/three

错误消息告诉我 npm i --save-dev @types/three,我照做了。这解决了导入错误,但是它打开了一大堆蠕虫:

我有一个要添加到场景中的 BoxComponent(我才刚刚开始使用反应三纤维,我想先从简单的盒子开始,然后再开始自定义导入的 .obj 文件)。它基于 another page from the official React Three Fiber Docs,经过初步调整以适应我的项目需求。这是它的基本内容:

import React, { useRef, useState } from "react";
import { BoxGeometryProps, useFrame } from "@react-three/fiber";

export interface BoxProps {
  position: Array<number>;
  optinalParam?: string;
}

const Box = (props: BoxProps) => {
  const ref = useRef(Object);
  const [hovered, hover] = useState(false);
  const [clicked, click] = useState(false);

  useFrame((state, delta) => {
    let refCurrent: BoxGeometryProps | undefined = ref.current; // [ERROR #1]
    if (refCurrent !== undefined) {
      refCurrent.rotation.z += 0.005; // [ERROR #2]
      refCurrent.rotation.x -= 0.005; // [ERROR #2]
    }
  });

  return (
    <mesh
      position={props.position} // [ERROR #3]
      ref={ref}
      scale={clicked ? 2.0 : 1}
      onClick={(event) => click(!clicked)}
      onPointerOver={(event) => hover(true)}
      onPointerOut={(event) => hover(false)}
    >
      <boxGeometry args={[1, 1, 1]} />
      <meshStandardMaterial color={hovered ? "lightgreen" : "lime"} />
    </mesh>
  );
};

export default function MyBox(props: BoxProps) {
  return (
    <>
      <Box position={props.position} />
    </>
  );
}

[错误 #1]:

Value of type 'ObjectConstructor' has no properties in common with type 'ExtendedColors<Overwrite<Partial<BoxGeometry>, NodeProps<BoxGeometry, typeof BoxGeometry>>>'. Did you mean to call it?ts(2560)
BoxComponent.tsx(21, 56): Did you mean to use 'new' with this expression?

[错误 #2]:

Property 'rotation' does not exist on type 'ExtendedColors<Overwrite<Partial<BoxGeometry>, NodeProps<BoxGeometry, typeof BoxGeometry>>>'.ts(2339)

[错误 #3]:

Type 'number[]' is not assignable to type 'Vector3 | undefined'.
Type 'number[]' is not assignable to type '[x: number, y: number, z: number]'.
Target requires 3 element(s) but source may have fewer.ts(2322)
three-types.d.ts(35, 5): The expected type comes from property 'position' which is declared here on type 'MeshProps'

刚才看了一下,我觉得最后一行可以找到解决方案three-types.d.ts(35, 5): The expected type...但是,老实说,我根本不知道@types包是如何工作的,而且,如前所述,我认为这可以在第 1 部分中解决,对此我会非常高兴。

我不经常 post 但我在这里很沮丧。我按照官方文档进行了一些小的扩展和调整,但是当我通过 npm 安装一个小包时,我的项目突然完全崩溃了。 非常期待您的帮助,非常非常感谢您。

P.S.,这是我的 package.json:

{
  "name": "myproject",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@emotion/react": "^11.8.2",
    "@emotion/styled": "^11.8.1",
    "@material-ui/core": "^4.12.3",
    "@mui/icons-material": "^5.5.1",
    "@mui/material": "^5.5.1",
    "@react-three/drei": "^8.16.4",
    "@react-three/fiber": "^7.0.26",
    "@testing-library/jest-dom": "^5.16.2",
    "@testing-library/react": "^12.1.2",
    "@testing-library/user-event": "^13.5.0",
    "@types/jest": "^27.4.0",
    "@types/node": "^17.0.17",
    "@types/react": "^17.0.44",
    "@types/react-dom": "^17.0.11",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-router-dom": "^6.2.1",
    "react-scripts": "^2.1.3",
    "three": "^0.137.5",
    "typescript": "^4.5.5",
    "uuid": "^8.3.2",
    "web-vitals": "^2.1.4",
    "zustand": "^3.7.2"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@types/three": "^0.140.0",
    "@types/uuid": "^8.3.4"
  }
}

更新:

我设法消除了所有错误。不能说我完全理解它,但它肯定与 useRef() 及其秘密魔法有关。在我的 BoxComponent 中为其提供“足够强大”的类型解决了问题:像这样:

之前:

const meshRef = useRef<BoxGeometryProps>(null);

之后:

const mesh = useRef<Mesh>(null);

使用直接从 three 导入的网格。我无法摆脱这种很快又会给我带来麻烦的感觉,因为我觉得我应该尽可能多地使用 react-three-fiber 中的东西,而不是 three。但是,现在,这个问题可以标记为已解决。