React + TypeScript + Eslintのエラーで苦しんだことのまとめ。

# 概要
React + TypeScriptに入門したんですが、
React + TypeScript + Eslintで開発環境を作成して、デフォルトアプリを動かすと、すでにワーニングが出てて、一体どういうことかと。

基本的にエラーや、ワーニングは消したい派なので、消し方のまとめを作成しました。
※今後も追加する予定。

## 1. Missing return type on function
デフォルトアプリで、出力されるワーニングで、関数の戻り値が明示されていない時に出力される。
App.tsxの5行目で出力されている。

```prompt:エラーメッセージ(1つ目)
src\App.tsx
  Line 5:1:  Missing return type on function  @typescript-eslint/explicit-module-boundary-types
```
対処: App.tsxの5行目を下記の修正で消える。

```diff_typescript:App.tsx(5)
  - function App() {
  + const App: React.FunctionComponent = () => {
```

src\reportWebVitals.tsの3行目で出力されている。

```prompt:エラーメッセージ(2つ目)
src\reportWebVitals.ts
  Line 3:25:  Missing return type on function  @typescript-eslint/explicit-module-boundary-types
```
対処: src\reportWebVitals.tsの3行目を下記の修正で消える。

```diff_typescript:src\reportWebVitals.ts(3)
  - const reportWebVitals = (onPerfEntry?: ReportHandler) => {
  + const reportWebVitals = (onPerfEntry?: ReportHandler): void => {
```

## 2. '〇〇' is missing in props validation eslint
受け取るプロパティのバリデーションをしてないよ。というエラー。

```prompt:エラーメッセージ
src\App.tsx
  Line 9:18:  'message' is missing in props validation  react/prop-types
```

エラーを吐いたコードと修正点。
エラーチェックの処理を追加することで、解決した。

```diff_typescript:App.tsx
import React from 'react';
+import PropTypes from 'prop-types';

type Props = {
  message: string,
}

const Child: React.FC<Props> = (props) => {
  return (
      <p>{ props.message }</p>
  );
}

const App: React.FC = () => {
    return (
    <div className="App">
      <Child message="子コンポーネント"/>
    </div>
  );
}

+Child.propTypes = {
+  message: PropTypes.string.isRequired,
+};

export default App;
```

## 3. Don't use `{}` as a type. `{}` actually means "any non-nullish value"
型タイプとして、`{}` を使とーばいという警告。
以下の実装で警告が発生していた。

```prompt:エラーメッセージ
src\App.tsx
  Line 8:51:  Don't use `{}` as a type. `{}` actually means "any non-nullish value".
- If you want a type meaning "any object", you probably want `Record<string, unknown>` instead.
- If you want a type meaning "any value", you probably want `unknown` instead.
- If you want a type meaning "empty object", you probably want `Record<string, never>` instead  @typescript-eslint/ban-types
```

エラーを吐いたコードと修正点。
"{}"を、"unknown"に変更したら、解決。

```diff_typescript:App.tsx
- class Detail extends React.Component<DetailProps, {}> {
+ class Detail extends React.Component<DetailProps, unknown> {
  render() {
    ...中略...
  }
}
```
## 4. Warning: You provided a `value` prop to a form field without an `onChange` handler.
`onChange`でないところで、` value`プロパティに値を設定したから。

解決方法は"value="を、"defaultValue="に修正したら、解決。

```prompt:エラーメッセージ
Warning: You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.
    at select
    at div
    at div
    at Detail (http://localhost:3000/static/js/main.chunk.js:52:1)
    at AdmisstionFeeCalculator (http://localhost:3000/static/js/main.chunk.js:206:5)
    at div
    at App
node_modules/react-error-overlay/lib/index.js:1
```

```diff_typescript:App.tsx
class Detail extends React.Component<DetailProps, unknown> {
  render() {
    return (
      <div className="flex">
        <div className="classification-name defmargin">{this.props.classification.name}</div>
        <div className="description defmargin">{this.props.classification.description}</div>
        <div className="unit-price defmargin">{this.props.classification.unitPrice}円</div>
        <div className="num-people defmargin">
-         <select value={this.props.classification.numOfPeople}>
+         <select defaultValue={this.props.classification.numOfPeople}>
            <option value="0">0</option>
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
            <option value="4">4</option>
          </select>
          <span>名</span>
        </div>
      </div>
    );
  }
}

class Summary extends React.Component {
  render () {
    return (
      <div className="flex">
        <div className="party defmargin" >
-         <input type="text" className="party" value="0" />
+         <input type="text" className="party" defaultValue="0" />
          <span>名様</span>
        </div>
        <div className="total-amount defmargin" >
          <span>合計</span>
-         <input type="text" className="total-amount" value="0" />
+         <input type="text" className="total-amount" defaultValue="0" />
          <span>円</span>
        </div>
      </div>
    );
  }
}
}
```

## 5. Type number trivially inferred from a number literal, remove type annotation  @typescript-eslint/no-inferrable-types

数値リテラルから簡単に推測される型は、宣言する必要ないよ。ってことらしい。
型宣言を、削除すると解決した。

```prompt:エラーメッセージ
src\App.tsx
  Line 20:11:  Type number trivially inferred from a number literal, remove type annotation  @typescript-eslint/no-inferrable-types
```

```diff_typescript:App.tsx
  onNumOfPeapleChange(e: React.ChangeEvent<HTMLSelectElement>): void{
-   const num: number = Number(e.target.value);
+   const num = Number(e.target.value);
    this.setState({numOfPeaple: num,});
  }
```

## 6. Unexpected empty constructor  @typescript-eslint/no-empty-function

空のコンストラクタは、許さん。ってことらしい。
コンストラクタにsuper()を追加したら、解決。

```prompt:エラーメッセージ
src\App.tsx
  Line 80:17:  Unexpected empty constructor  @typescript-eslint/no-empty-function
```

```diff_typescript:App.tsx
class AdmisstionFeeCalculator extends React.Component<unknown, AdmisstionFeeCalculatorState> {
  constructor() {
+   super('aaaaa');
  }
```

## 7. Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

訳が分からん。
起きたのは、"const [str, setStr] = useState("0");"のコードを自分で追加した時なので、修正場所もわかるけど、
他人のコードで起きたら絶対分からんと思う。
フックの呼び方が悪いらしい。

```prompt:エラーメッセージ
Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
```
ひとまず、追加した下記コードを削除すると解決。
"const [str, setStr] = useState("0");"

## 8. Property 'firestore' does not exist on type 'FirebaseApp'
プロパティ 'firestore' は型 'FirebaseApp' に存在しません。ts(2339)

Firebaseと、連携したWebアプリを作ろうとしたら、発生。
バージョンを、古いのにインストールしなおしたら、治った。

```prompt:エラーメッセージ
D:/Products/React.js/firebase-react-todo_fail001/src/firebase.ts
TypeScript error in D:/Products/React.js/firebase-react-todo_fail001/src/firebase.ts(16,32):
Property 'firestore' does not exist on type 'FirebaseApp'.  TS2339

    14 | });
    15 | 
  > 16 | export const db  = firebaseApp.firestore();
       |                                ^
    17 | export const auth= firebase.auth();
    18 |
```

```prompt:
npm install --save firebase <---------- これでversion 9.0.0がインストールされた。
npm install --save firebase@8.10.0 <--- なので、version 8.10.0を指定してインストール仕直した。
```
該当するバージョンは下記コマンドで調べた。

```prompt:
npm info firebase versions
```

## 9. Missing "key" prop for element in iterator

React HooksのWebアプリを作っている時に、発生。
&lt;div&gt;タグに、"key"属性を追加したら治った。
hookする時は、key属性を設定せんといかんらしい。

```prompt:エラーメッセージ
src\App.tsx
  Line 21:26:  Missing "key" prop for element in iterator  react/jsx-key

Search for the keywords to learn more about each error.
```

```diff_typescript:App.tsx
-     {tasks.map((task)=><h3>{task.id} {task.title}</h3>)}
+     {tasks.map((task)=><h3 key={task.id}>{task.id} {task.title}</h3>)}
  }
```

## 10. 'React' must be in scope when using JSX  react/react-in-jsx-scope
```prompt:エラーメッセージ
src/Game.tsx
  Line 3:9:  'React' must be in scope when using JSX  react/react-in-jsx-scope
```
React公式チュートリアルを[typescriptで再作成](https://zenn.dev/rg687076/articles/7770d0eb164052)している時に、発生。
ファイルの先頭に、importを追加したら直った。
import React from 'react';
2020年末リリースの[React v17](https://ja.legacy.reactjs.org/blog/2020/10/20/react-v17.html)の変更が影響しているらしい。

```diff_typescript:Game.tsx
+ import React from 'react';
const Game = () => {
    return (
        <div className="App">
            Hello World!!!
        </div>
    );
}

export default Game;
```

## 11. Unexpected empty arrow function @typescript-eslint/no-empty-function
```prompt:エラーメッセージ
src/Game.tsx
  Line 63:104:  Unexpected empty arrow function @typescript-eslint/no-empty-function
```
空関数はダメだって。

```diff_typescript:Game.tsx
const Game = () => {
    return (
        <div className='game-board'>
-           <Board squares={[null, null, null, null, null, null, null, null, null]} onClick={() => {} } />
-           // ↑この行のonClick。
+           <Board squares={[null, null, null, null, null, null, null, null, null]} onClick={() => {console.log('aaa')} } />
+           // ↑onClickにconsole.log()を追加した。
        </div>
    );
}

export default Game;
```

onClickにconsole.log()を追加したら、解決。

## 12. Type number trivially inferred from a number literal, remove type annotation.
```prompt:エラーメッセージ
src/components/QRCodeScanner.tsx
  Line 4:7:  Type number trivially inferred from a number literal,
```
"数値リテラルから推測できるから、型指定を削除してね。"だって。
どげんでんよか、余計なお世話やし!! せいぜい警告やろ!!

```diff_typescript:QRCodeScanner.tsx
- const videoWidth: number = 500;
- const videoHeight: number = 500;
- const videoFrameRate: number = 5;
+ const videoWidth = 500;
+ const videoHeight = 500;
+ const videoFrameRate = 5;
```

## 13. R3F: Hooks can only be used within the Canvas component!
```prompt:エラーメッセージ
ERROR
R3F: Hooks can only be used within the Canvas component!
    at useStore (http://localhost:3000/static/js/bundle.js:2348:21)
    at useFrame (http://localhost:3000/static/js/bundle.js:2366:17)
    at App (http://localhost:3000/static/js/bundle.js:102:56)
    at renderWithHooks (http://localhost:3000/static/js/bundle.js:23374:22)
    at mountIndeterminateComponent (http://localhost:3000/static/js/bundle.js:26658:17)
    at beginWork (http://localhost:3000/static/js/bundle.js:27954:20)
    at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:12970:18)
    at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:13014:20)
    at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:13071:35)
    at beginWork$1 (http://localhost:3000/static/js/bundle.js:32935:11)
```

react three fiber(R3F リアクトの3D表示ライブラリ)を使ってて発生。
useFrame()は<Canvas />の中でしか使えんばいと言ってる。

```diff_typescript:App.tsx
const App = () => {
  const textRef = useRef({} as any)
  useFrame(() => {                     // ← ここで発生
    textRef.current.rotation.x += 0.01 // ← ここで発生
  });                                  // ← ここで発生

  return (
    <div id="canvas-container">
      <Canvas>
        <ambientLight />
        <pointLight position={[10, 10, 10]} />
        <Box position={[-1.2, 0, 0]} />
        <Box position={[1.2, 0, 0]} />
        <Text ref={textRef} position={[-2, 1, 0]} font="/Roboto-Black.ttf" fontSize={1} color={'#ff0203'}>HELLO</Text>
        <Text2 position={[1, 0, 2]} font="/Roboto-Black.ttf" fontSize={1} color={'#03ffff'}>WORLD</Text2>
      </Canvas>
    </div>
  );
}

export default App;
```
↓
修正後
```diff_typescript:App.tsx
+const Text2 = (props: { children?: string, position?: [x:number, y: number, z:number], font?: string, fontSize?: number, color?: ReactThreeFiber.Color}) => {
+ const texsRef = useRef({} as any)
+ useFrame(() => {
+   texsRef.current.rotation.x += 0.01
+ });
+
+ return (
+   <group ref={texsRef}>
+       <Text position={props.position} font={props.font} fontSize={props.fontSize} color={props.color}>{props.children}</Text>
+    </group>
+ )
+}

const App = () => {
- const textRef = useRef({} as any)
- useFrame(() => {                     // ← ここで発生
-   textRef.current.rotation.x += 0.01 // ← ここで発生
- });                                  // ← ここで発生

  return (
    <div id="canvas-container">
      <Canvas>
        <ambientLight />
        <pointLight position={[10, 10, 10]} />
        <Box position={[-1.2, 0, 0]} />
        <Box position={[1.2, 0, 0]} />
-       <Text ref={textRef} position={[-2, 1, 0]} font="/Roboto-Black.ttf" fontSize={1} color={'#ff0203'}>HELLO</Text>
+       <Text2 ref={textRef} position={[-2, 1, 0]} font="/Roboto-Black.ttf" fontSize={1} color={'#ff0203'}>HELLO</Text>
        <Text2 position={[1, 0, 2]} font="/Roboto-Black.ttf" fontSize={1} color={'#03ffff'}>WORLD</Text2>
      </Canvas>
    </div>
  );
}

export default App;
```
Textクラスのラッパーとして、Text2を作って、そっちでuseFrame()を実行する様に修正することで直った。

## 14. Type 'MutableRefObject<Mesh< ～略～ Types of property 'current' are incompatible.
react three fiber(R3F)と@react-three/dreiを使ってて発生。
16行目の refとcubeの型が違うばい。って言ってる。

```ts:エラーメッセージ
ERROR in src/App.tsx:16:11
TS2322: Type 'MutableRefObject<Mesh<BufferGeometry<NormalBufferAttributes>, Material | Material[], Object3DEventMap> | undefined>' is not assignable to type 'Ref<Mesh<BufferGeometry<NormalBufferAttributes>, Material | Material[], Object3DEventMap>> | undefined'.
  Type 'MutableRefObject<Mesh<BufferGeometry<NormalBufferAttributes>, Material | Material[], Object3DEventMap> | undefined>' is not assignable to type 'RefObject<Mesh<BufferGeometry<NormalBufferAttributes>, Material | Material[], Object3DEventMap>>'.
    Types of property 'current' are incompatible.
      Type 'Mesh<BufferGeometry<NormalBufferAttributes>, Material | Material[], Object3DEventMap> | undefined' is not assignable to type 'Mesh<BufferGeometry<NormalBufferAttributes>, Material | Material[], Object3DEventMap> | null'.
        Type 'undefined' is not assignable to type 'Mesh<BufferGeometry<NormalBufferAttributes>, Material | Material[], Object3DEventMap> | null'.
    14 |
    15 |   return (
             const cube = useRef<THREE.Mesh>()
  > 16 |     <mesh ref={cube}>
       |           ^^^
    17 |       <boxBufferGeometry args={[1, 1, 1]} />
    18 |       <meshStandardMaterial color="#0391BA" />
    19 |     </mesh>
```

null!を引数に追加したら直った。
※エラーメッセージが分からなすぎる。
```ts:エラーメッセージ
const cube = useRef<THREE.Mesh>(null!)
                                ^^^^^
```

## 15. Unknown property 'intensity' found  react/no-unknown-property
react three fiber(R3F)と@react-three/dreiを使ってて発生。
intensityってプロパティ、ないばいってeslintが怒ってる。

```ts:エラーメッセージ
[eslint] 
src/App.tsx
  Line 28:19:  Unknown property 'intensity' found  react/no-unknown-property

Search for the keywords to learn more about each error.
```

.eslintrc.jsに、下記設定を追加。
```ts:エラーメッセージ
    "rules": {
        "react/no-unknown-property": ['error', { ignore: ["intensity", "position",'args'] }],
                                                           ^^^^^^^^^
    }
```

## 16.Property 'wireframe' does not exist on type 'Material | Material[]'.  Property 'wireframe' does not exist on type 'Material'.
react three fiber(R3F)と@react-three/dreiを使ってて発生。
ref.current.materialにwireframeってプロパティって、ないばいってeslintが怒ってる。
refの正体は、mesh。その子供に"meshBasicMaterial"を持ってる構造となっている。ref.current.materialで、meshBasicMaterialが取れることを期待するけど、実は、materialはその親クラスのMaterialで、Materialは、wireframe を持ってないので、怒られた。
```ts:
<mesh ref={ref}>
 <meshBasicMaterial color={0x00ff00} wireframe />
</mesh>
```


```ts:エラーメッセージ
ERROR in src/App.tsx:25:30
TS2339: Property 'wireframe' does not exist on type 'Material | Material[]'.
  Property 'wireframe' does not exist on type 'Material'.
    23 |       value: false,
    24 |       onChange: (v: boolean) => {
  > 25 |         ref.current.material.wireframe = v
       |                              ^^^^^^^^^
```

.eslintrc.jsに、下記処理を追加。
呼び元のMaterial要素に合う様に、キャストしたげて、wireframeに値を設定するようにした。
※boxprops.props.nameには、クラス名を自分で設定している。
```ts:App.tsx
        if(boxprops.props.name == "meshBasicMaterial")
          (ref.current.material as THREE.MeshBasicMaterial).wireframe = v
        else if(boxprops.props.name == "meshNormalMaterial")
          (ref.current.material as THREE.MeshNormalMaterial).wireframe = v
        else if(boxprops.props.name == "meshPhongMaterial")
          (ref.current.material as THREE.MeshPhongMaterial).wireframe = v
        else if(boxprops.props.name == "meshStandardMaterial")
          (ref.current.material as THREE.MeshStandardMaterial).wireframe = v
```

## 17.-1.SyntaxError: Unexpected token ‘<’, "<!DOCTYPE "... is not valid JSON at JSON.parse ()
at GLTFLoader.parse (GLTFLoader.js:315:21)
at Object.onLoad (GLTFLoader.js:205:11)
at three.module.js:39951:38

react three fiber(R3F)で、GLTFLoaderを使って、3Dモデルを表示させようとして発生。
原因不明だけど、index.htmlの中身を読みに行ってるようなふるまいをしている。

下記コードで発生しているけど。。。
```
const gltf = useLoader(GLTFLoader, 'models/Totoro.glb')
```
↑第2引数も間違ってない
モデルもpublic/models/Totoro.glbに置いてて、間違いの要素がない。
解決策 : プロジェクト一式を削除して、gitから再取得 -> npm install -> npm startで動いた!!
これ、reactの不具合なんじゃね？

## 17.-2.Could not load /bedroom3d.glb: Unexpected token '<', "<!DOCTYPE "... is not valid JSON
```prompt:エラーメッセージ
Could not load /bedroom3d.glb: Unexpected token '<', "<!DOCTYPE "... is not valid JSON
    at http://localhost:3000/static/js/bundle.js:3690:36
    at _onError (http://localhost:3000/static/js/bundle.js:87992:9)
    at Object.onLoad (http://localhost:3000/static/js/bundle.js:88011:9)
    at http://localhost:3000/static/js/bundle.js:119566:39
```

また、こいつが出た。
react three fiber(R3F)で、GLTFJSXを使ってて、出力させたTSXファイルをプロジェクトに追加して表示させようとして発生。
具体的には、TSXファイルの中の*.glb読込みで失敗している。
モジュールの読込みに失敗した系だと、"Unexpected token '<', "<!DOCTYPE "... is not valid JSON"が表示されるらしい。
```diff_typescript:Bedroom3d.tsx
- const { nodes, materials } = useGLTF('/bedroom3d.glb') as GLTFResult
+ const { nodes, materials } = useGLTF('assets/bedroom3d.glb') as GLTFResult
//                                      ↑読込みパスを修正
～略～
- useGLTF.preload('/bedroom3d.glb')
+ useGLTF.preload('assets/bedroom3d.glb')
//                 ↑読込みパスを修正
```
読込みのパスを正しく設定したら直った。

## 18.Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ KeyA: number; KeyD: number; KeyW: number; KeyS: number; }'.

Typescriptで、json使ったら発生。
素のjsonだとAny型になるので、値へのアクセス方法が分からんらしい。
型情報をつけてあげたら直った。

エラー内容
```ts:App.tsx
ERROR in src/App.tsx:17:41
TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ KeyA: number; KeyD: number; KeyW: number; KeyS: number; }'.
  No index signature with a parameter of type 'string' was found on type '{ KeyA: number; KeyD: number; KeyW: number; KeyS: number; }'.
    15 |     // const keystr = "'" + key + "'"
    16 |     // console.log("aaaa key=" + 'KeyA' + ", value=" + keyIndexPair[keystr]);
  > 17 |     console.log(" keyIndexPair[xxx]=" + keyIndexPair[key]);
       |                                         ^^^^^^^^^^^^^^^^^
    18 |   });
    19 |   const keystr = 'KeyA' 
    20 |   console.log("aaaa key=" + 'KeyA' + ", value=" + keyIndexPair[keystr]);
```

エラーの実装
```ts:App.tsx
  const keyIndexPair = {'KeyA': 0, 'KeyD': 1,'KeyW': 2,'KeyS': 3,}
  Object.keys(keyIndexPair).forEach((key, value) => {
    console.log(" keyIndexPair[xxx]=" + keyIndexPair[key]);
                                                     ↑↑↑ここ
  });
```
型情報をつけてあげる。
```diff_typescript:App.tsx
+ type typekeyIndexPair = {[key: string]: number }
+ const keyIndexPair: typekeyIndexPair = {'KeyA': 0, 'KeyD': 1,'KeyW': 2,'KeyS': 3,}
- const keyIndexPair = {'KeyA': 0, 'KeyD': 1,'KeyW': 2,'KeyS': 3,}
  const keyMap = useRef<boolean[]>(null!)
  Object.keys(keyIndexPair).forEach((key, value) => {
    console.log(" keyIndexPair[xxx]=" + keyIndexPair[key]);
  });
```
したら、直った。
TypeScript分かりづらい～。

## 19.Property 'children' is missing in type '{ camera: { position: [number, number, number]; }; }' but required in type 'CanvasProps'.ts(2741) Canvas.d.ts(5, 5): 'children' is declared here.

windows環境のreact three fiber(R3F)で、開発初めに発生。
<Canvas>タグには子要素をつけろって怒ってる。

下記コードで発生。
```ts:App.tsx
const App = () => {
  const ref = useRef<OrbitControlsProps>(null!)

  return (
    <div style={{ width: "75vw", height: "75vh" }}>
      <Canvas camera={{ position: [8, 2, 12] }}>
              ^^^^^^
      </Canvas>
    </div>
  );
}
```

子要素追加したら消えた。
```ts:App.tsx
const App = () => {
  const ref = useRef<OrbitControlsProps>(null!)

  return (
    <div style={{ width: "75vw", height: "75vh" }}>
      <Canvas camera={{ position: [8, 2, 12] }}>
        <OrbitControls /> ← これを追加したら消えた
         ^^^^^^^^^^^^^^
      </Canvas>
    </div>
  );
}
```

## 20.Type 'MutableRefObject<OrbitControlsProps>' is not assignable to type 'Ref<OrbitControls> | undefined'. Type 'MutableRefObject<OrbitControlsProps>' is not assignable to type 'RefObject<OrbitControls>'.　The types of 'current.object' are incompatible between these types. Type 'PerspectiveCamera | OrthographicCamera | undefined' is not assignable to type 'PerspectiveCamera | OrthographicCamera'. Type 'undefined' is not assignable to type 'PerspectiveCamera | OrthographicCamera'.ts(2322) index.d.ts(119, 9): The expected type comes from property 'ref' which is declared here on type 'IntrinsicAttributes & OrbitControlsProps & RefAttributes<OrbitControls>'


```shell:エラーメッセージ
Type 'MutableRefObject<OrbitControlsProps>' is not assignable to type 'Ref<OrbitControls> | undefined'.
  Type 'MutableRefObject<OrbitControlsProps>' is not assignable to type 'RefObject<OrbitControls>'.
    The types of 'current.object' are incompatible between these types.
      Type 'PerspectiveCamera | OrthographicCamera | undefined' is not assignable to type 'PerspectiveCamera | OrthographicCamera'.
        Type 'undefined' is not assignable to type 'PerspectiveCamera | OrthographicCamera'.ts(2322)
index.d.ts(119, 9): The expected type comes from property 'ref' which is declared here on type 'IntrinsicAttributes & OrbitControlsProps & RefAttributes<OrbitControls>'
```

```ts
const App = () => {
  const ref = useRef<OrbitControlsProps>(null!)

  return (
    <div style={{ width: "75vw", height: "75vh" }}>
      <Canvas camera={{ position: [8, 2, 12] }}>
        <OrbitControls ref={ref} target={[8, 2, 3]} />
                           ^^^^^ ここでエラー。
      </Canvas>
    </div>
  );
}
```
useRefに設定した、OrbitControlsPropsが型違いって怒られた。
じゃ、何設定すりゃいいと？

下記、OrbitControlsImplを設定すると直った。
```diff_typescript
+ import { OrbitControls as OrbitControlsImpl } from 'three-stdlib' 
const App = () => {
- const ref = useRef<OrbitControlsProps>(null!)
+ const ref = useRef<OrbitControlsImpl>(null!)

  return (
    <div style={{ width: "75vw", height: "75vh" }}>
      <Canvas camera={{ position: [8, 2, 12] }}>
        <OrbitControls ref={ref} target={[8, 2, 3]} />
      </Canvas>
    </div>
  );
}
```
ホント、typescriptは分かりにくい。
腹立つわ～。

## 21. <br/>npm ERR! enoent ENOENT: no such file or directory, lstat 'C:\Users\xxx\AppData\Roaming\npm'<br/>npm ERR! enoent This is related to npm not being able to find a file.

windows11環境のreact three fiber(R3F)開発にて。
Blenderモデルの読み込みコンポーネントを生成するため、git gltfjsxコマンドを実行すると下記エラーが発生。

```shell:エラーメッセージ
D:\Products\React.js\react-r3f-advanced002> npx gltfjsx public\assets\Apartment2.glb --types --shadows
npm ERR! code ENOENT
npm ERR! syscall lstat
npm ERR! path C:\Users\jun\AppData\Roaming\npm
npm ERR! errno -4058
npm ERR! enoent ENOENT: no such file or directory, lstat 'C:\Users\xxx\AppData\Roaming\npm'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent
npm ERR! A complete log of this run can be found in: C:\Users\xxx\AppData\Local\npm-cache\_logs\2024-01-01T07_24_51_603Z-debug-0.log
```
'C:\Users\xxx\AppData\Roaming\'配下にnpmフォルダがないかららしい。
npmフォルダを作って実行したら、解決。

```shell:正常終了
D:\Products\React.js\react-r3f-advanced002> npx gltfjsx public\assets\Apartment2.glb --types --shadows
/*
Auto-generated by: https://github.com/pmndrs/gltfjsx
Command: npx gltfjsx@6.2.16 public\assets\Apartment2.glb --types --shadows
*/
```

## 22. Type 'IterableIterator<number>' can only be iterated through when using the '--downlevelIteration' flag or with a '--target' of 'es2015' or higher.

React+TypeScriptで、下記コードで発生。

```html
<Center>
  {[...Array(5).keys()].map(() => { return <></>})
<!--   ^^^^^^^^^^^^^^^    ← ここで発生!!-->
  }
</Center>
```

tsconfig の compilerOptionsで、
target : es5 の時に、downlevelIteration をtrueを追加すると直った。
```json
  "compilerOptions": {
    "downlevelIteration": true,   ##  ← これを追加
    "target": "es5",
    "lib": [
```
downlevelってのが気持ち悪いけど、直ったからいいや。

## 23. 'React' must be in scope when using JSX  react/react-in-jsx-scope

React+TypeScriptで、新規tsxファイルを読込むようにすると発生。
新規のtsxファイルの方で、 \Reactをimportしろって言ってる。

```ts:App.tsx
import Eve from './Eve'
```

```diff_tsx:Eve.tsx
+import React from 'react';
const Eve = () => {
    return (<></>)
}
export default Eve;
```
import Reactを追加したら解決。


まだまだ、修行中。。。