TypeScript
You may want to use TypeScript when developing your React Three Fiber applications.
TypeScript is a tool that you can use when developing, to help you make sure all your code is type safe. I.e., if you need to pass an integer to a function, but you write it as a string instead, then the TypeScript compiler will notify you while developing.
Using TypeScript is optional, and many syntax issues can already be found if using ESLint as described at ESLint.
Using TypeScript in a React application requires some extra considerations since types are not automatically inferred when using hooks such as the useRef hook.
Visit the official Pmdrns.docs for in introduction of using TypeScript with React Three Fiber.
Continued below on this page is some extra information based on my personal experience.
So, starting from one of the courses React Three Fiber boilerplate branches, I will use the Leva
branch.
git clone https://github.com/Sean-Bradley/React-Three-Fiber-Boilerplate.git
cd React-Three-Fiber-Boilerplate
git checkout leva
npm install
npm start
Rename extensions from jsx
to tsx
Rename files with the jsx
extension, to use the tsx
extension.
App.jsx --> App.tsx
index.jsx --> index.tsx
Polyhedron.jsx --> Polyhedron.tsx
The files may now show some errors and warnings when viewing in the IDE.
Install TypeScript
Press CtrlC a few times to stop the development webserver and execute,
npm install typescript --save-dev
Note that when installing typeScript@5.x.x
, react-scripts@5.0.1
will have a conflict.
We can fix it now by adding an overrides
section to your package.json
that matches the version of TypeScript installed. This fix is only required if using react-scripts@5.0.1
.
// ... existing package.json
},
"devDependencies": {
"typescript": "^5.1.3"
},
"overrides": {
"typescript": "^5.1.3"
}
}
Add tsconfig.json
Add a tsconfig.json
to your projects root folder. Add the contents below and save.
{
"include": ["./src/**/*"],
"compilerOptions": {
"strict": true,
"esModuleInterop": true,
"lib": ["dom", "es2015"],
"jsx": "react-jsx"
}
}
Install Type Definitions
The IDE will read your code and try to match the types to it. You can tell it which definition files to use.
npm install @types/node --save-dev
npm install @types/react --save-dev
npm install @types/react-dom --save-dev
npm install @types/three --save-dev
After installing type definitions, it can take some time for the IDE to catch up. Try pressing F1, and select "Restart TS Server". This technique can also work for CodeSandbox projects.
Also note that you should try to match the versions of the types with the library installed.
E.g., If you are using Three@0.152.1
then install the closest @types/three
version such as,
npm install @types/three@0.152.1 --save-dev
Note
Since the type definitions are developed separately from the main library, the latest version numbers won't always be in sync. Just try to match the closest number that you can, and you may not experience any issues unless you are using some part of the library where the method signature was recently changed.
Fix index.tsx
In index.tsx
, the IDE is unsure what type is being returned from the document.getElementById
method. We can cast the type as a HTMLDivElement
.
Change the createRoot
line from,
createRoot(document.getElementById('root')).render(
to
createRoot(document.getElementById('root') as HTMLDivElement).render(
When working with TypeScript, you often need to figure out the correct type of variable, or the value a method returns.
If you get stuck trying to figure out the most appropriate types, then you can cast as any
.
createRoot(document.getElementById('root') as any).render(
Or, you can add the directive // @ts-ignore
before the line containing the error.
// @ts-ignore
createRoot(document.getElementById('root')).render(
Fix Polyhedron.tsx
There are several problems in this file, lets look at Binding element 'polyhedron' implicitly has an 'any' type
The Polyhedron function is using destructuring assignment and a rest (...) operator.
Since when creating the Polyhedron, which is based on a THREE.Mesh
, but with some extra custom attributes, I have chosen to create an interface named IPolyhedron
which extends from the R3F MeshProps
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
Also, since there is a useRef
hook pointing to a mesh
JSX element, I have declared it as,
const ref = useRef<THREE.Mesh>(null!)
Also, I needed to cast color as THREE.Color
to avoid a problem in App.tsx
where it passed the value as a string, and Leva could pass as a color, but the JSX in Polyhedron.tsx
requires it to be a THREE.Color
.
// line 20 App.tsx
color: {
value: 'lime'
}
// line 6 Polyhedron.tsx optional THREE.Color or String
color: THREE.Color | String
// line 27 Polyhedron.tsx
<meshBasicMaterial color={color as THREE.Color} wireframe />
npm start
All problems should now be solved, we can run,
npm start
Useful links
Leva (TypeScript version) | CodeSandbox |
Materials (TypeScript version) | CodeSandbox |
useGLTF (TypeScript version) | CodeSandbox |
Working Example
GitHub Branch
git clone https://github.com/Sean-Bradley/React-Three-Fiber-Boilerplate.git
cd React-Three-Fiber-Boilerplate
git checkout leva-typescript
npm install
npm start
Troubleshooting
'React' refers to a UMD global, but the current file is a module. Consider adding an import instead.
Ensure you have a tsconfig.json
and that you have installed the type definitions for both React and React-dom.
npm install @types/react --save-dev
npm install @types/react-dom --save-dev
If using VSCode or CodeSandbox, then you can press F1 and select "Restart TS Server" to re-scan the type definitions.
TypeError: THREE.Vector3 is not a constructor
I have seen this happen when using react-scripts@5.0.1
with typescript@4.x.x
and @react-three/drei
.
Upgrade to TypeScript 5.
npm install typescript@latest
If still using react-scripts@5.0.1
, then you will need to add an overrides
section to your package.json
that matches the version of TypeScript that you've installed.
// ... existing package.json
"typescript": "^5.1.3"
},
"overrides": {
"typescript": "^5.1.3"
}
}
npm ERR! While resolving: react-scripts@5.0.1
When executing npm install
you get an error,
npm install
npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR!
npm ERR! While resolving: react-scripts@5.0.1
npm ERR! Found: typescript@5.x.x