I am currently having issues with TypeScript configuration in my project.
Firstly, I developed my application using regular JavaScript. Then, wanting to learn TypeScript, I converted my JavaScript project into a TypeScript project.
To do this, I ran a yarn add typescript command and added the required types for Node.js, React, React-DOM, and React-Router-DOM.
I am currently using:
- React.JS: v18.2.0
- Vite.JS: 4.2.0
- TypeScript: v5.0.2
There is my configuration files for running typescript:
tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false,
"skipLibCheck": true,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
},
"include": ["src/**/*"],
"references": [{ "path": "./tsconfig.node.json" }]
}
tsconfg.node.json
{
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}
vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react({
include: '**/*.tsx'
})],
server: {
port: 3000
},
esbuild: {
loader: "jsx",
},
optimizeDeps: {
esbuildOptions: {
loader: {
".js": "jsx",
".ts": "tsx",
},
},
},
});
If i try using types :
index.ts
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
There is my vite error:
[plugin:vite:esbuild] Transform failed with 1 error:
/var/www/remote/dashboard/src/index.ts:25:65: ERROR: Expected ")" but found "as"
/var/www/remote/dashboard/src/index.ts:25:65
Expected ")" but found "as"
23 |
24 |
25 | const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
| ^
26 |
27 | root.render(<RecoilRoot><App /></RecoilRoot>);
My project is running perfectly if i not use any thing of typescript.
2
Answers
I think the underlying problem here is that
document.getElementById
can return either anHTMLElement
ornull
. Because of this, when you try and pass it into thecreateRoot
method, typescript throws an error. It is throwing this error because thecreateRoot
method takes in anHTMLElement
type but not anull
type. The compiler is telling you that you need to make sure the return ofdocument.getElementById
is notnull
before you try and use it.To mitigate this error you are attempting to assert the return type of
getElementById
to anHTMLElement
. Since you are doing so inside of the function parenthesis you are getting a syntax error.To fix this, the correct way, you should check to make sure that the return from
document.getElementById
has a value before attempting to use it (things like this are one of the many reasons for typescript):This way, you are not forcing the compiler to ignore something and you actually have typesafe code.
On the other hand, if you are 10000% sure this will never return
null
, you can narrow the type by casting with theas
keyword. You just need to group it in a way that does not throw a syntax error:Note that using the
as
keyword in this instance is basically forcing typescript to act like javascript. You should use the first method above IMHO.It appears that the Vite configuration is not properly set up to handle TypeScript files. Please update your vite.config.ts file to include the TypeScript loader for esbuild and the appropriate file extensions. Here’s the modified vite.config.ts file:
This configuration sets the default esbuild loader to "tsx" and adds a regex pattern to include both TypeScript (.ts) and TypeScript with JSX (.tsx) files.
Additionally, there is a syntax error in your tsconfig.json file. You have an extra trailing comma in the "jsx": "react-jsx" line. Remove the comma, and it should look like this:
After updating your Vite configuration and fixing the syntax error in tsconfig.json, your project should now work correctly with TypeScript.