skip to Main Content

I recently started using Vite 4.1.0 to build my React-Redux project with typescript. As we know, typescript ensures that everything is ‘typed’ and has some type associated with it.

I am coding in Visual Studio Code, and this IDE clearly is pointing out that there is a typescript error (even showing red squiggly line), but Vite is just ignoring it and compiling the code and running it successfully.

Here is the example I am talking about.

UserView.tsx

import React from 'react'
import { useAppDispatch, useAppSelector } from '../../app/hooks'
import { fetchUserDetails, typeIntialState } from './userSlice'

export default function UserView() {

    const users = useAppSelector((state) => state.user)
    const dispatch = useAppDispatch()

    const getUsers = () => {
        dispatch(fetchUserDetails())
    }
    return (
        <div>
            <h1>Users</h1>
            {!users.isLoading && users.data.length ? (
                <ul>
                    {
                        users.data.map(user => (
                            <li key={user.id}>{user.email}</li>
                        ))

                    }
                </ul>
            ) : null}
            <button onClick={() => getUsers()}>Generate Users</button>
        </div>
    )
}

And this is the user slice file

userSlice.ts

import { createAsyncThunk, createSlice, PayloadAction } from "@reduxjs/toolkit"
import axios from "axios"

interface User {
    id: number,
    name: string
}

interface InitialState  {
    isLoading: boolean,
    data: User[],
    error: string
}

const initialState : InitialState = {
    isLoading: false,
    data: [],
    error: ''
}

export const fetchUserDetails = createAsyncThunk('user/fetchUserDetails', () => {
    return axios
            .get('https://jsonplaceholder.typicode.com/users')
            .then((response) => response.data)
})


const userSlice = createSlice({
    name: 'user',
    initialState,
    reducers: {},
    extraReducers: (builder) => {
        builder.addCase(fetchUserDetails.pending, (state) => {
            state.isLoading = true
        }),
        builder.addCase(fetchUserDetails.fulfilled, (state, action : PayloadAction<User[]>) => {
            state.isLoading = false
            state.data = action.payload
            state.error = ''
            console.log(state.data)
        }),
        builder.addCase(fetchUserDetails.rejected, (state, action ) => {
            state.isLoading = false
            state.data = []
            state.error = action.error.message || "Something went wrong"
        })
    },
})

export default userSlice.reducer

export type typeIntialState = typeof initialState

Here, in my userSlice.ts file, I have the User interface, which takes in only ‘id’ and ‘name’ property. However, in UserView.tsx, I am accessing user.email which is NOT a property of User interface.

This is flagged down by IDE and shows red squiggly, but Vite just goes up and builds without throwing any error.

I have tried migrating the SAME code without Vite and it is throwing error as expected and not building.

So, my question is, how do I make Vite throw me error when typescript is violated.

3

Answers


  1. This is a bit confusing when you come from a compiled language like C or Java but is what Typescript is supposed to do. At it’s core the Typescript compiler does two things:

    1. Generating Javascript code from your Typescript code
    2. Checking the code for type errors

    The compiler does both of those things independent from each other. This means that you can write Typescript code that has type errors and emits valid Javascript.

    Example (copied from the excellent book "Effective Typescript" by Dan Vanderkam):

    $ cat test.ts
    let x = 'hello';
    x = 1234;
    $ tsc test.ts
    test.ts:2:1 - error TS2322: Type '1234' is not assignable to type 'string'
    2 x = 1234;
     ~
    $ cat test.js
    var x = 'hello';
    x = 1234;
    
    Login or Signup to reply.
  2. Vite doesn’t support typechecking TypeScript code, because it works by transpiling each module in isolation as per the documentation. This makes it impossible to properly typecheck the project as a whole.

    After coming across this problem while working with Svelte, I have found that the vite-plugin-checker plugin for Vite works really well to provide type checking in Vite.

    All I had to do was add the plugin in vite.config.ts:

    export default defineConfig({
      plugins: [
        checker({
          typescript: true,
        }),
        svelte(),
      ],
    })
    
    Login or Signup to reply.
  3. I would recommend to you to use the vite-plugin-checker

    • Step 1: npm i vite-plugin-checker -D
    • Step 2: Change vite.config.ts import: import checker from 'vite-plugin-checker'
    • Step 3: Add Typescript check to plugins like this:
      checker({ typscript: true, }),

    See example config:

    import {defineConfig} from 'vite'
    import vue from '@vitejs/plugin-vue'
    import {resolve} from 'path'
    import {VitePWA} from 'vite-plugin-pwa'
    import checker from 'vite-plugin-checker'
    
    // https://vitejs.dev/config/
    export default defineConfig({
        resolve: {
            alias: {
                '@': resolve(__dirname, './src/components')
            },
        },
        plugins: [
            vue(),
            VitePWA({registerType: 'autoUpdate'}),
            checker({
                typescript: true,
            }),
        ],
    })
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search