Published on

Fixing 'test' does not exist in type 'UserConfigExport' in Vitest

Authors
  • Name
    Ripal & Zalak
    Twitter

How to Fix 'test' does not exist in type 'UserConfigExport' in Vitest

When setting up Vitest for a Vite project using TypeScript, you might encounter the following error:

ts(2345): Object literal may only specify known properties, and 'test' does not exist in type 'UserConfigExport'.

This error typically occurs due to a mismatch between the configurations of Vitest and Vite. This blog will guide you through the root cause and solutions to resolve this issue.

Problem

You’re trying to configure Vitest in your vite.config.ts file as follows:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  test: {
    globals: true,
    environment: 'jsdom',
  },
  plugins: [vue()],
})

When using VS Code or running TypeScript, the error appears:

Argument of type '{ test: { globals: boolean; environment: string; }; plugins: Plugin[]; }' is not assignable to parameter of type 'UserConfigExport'.

This happens because the test property is not recognized by Vite's default configuration. The test field is specific to Vitest and requires the correct configuration context.

Solution

1. Use vitest/config Instead of vite

The simplest solution is to import defineConfig from vitest/config instead of vite. Vitest extends Vite's configuration, enabling the test property.

import { defineConfig } from 'vitest/config'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  test: {
    globals: true,
    environment: 'jsdom',
  },
})

2. Add TypeScript Reference

Another approach is to add a TypeScript reference to Vitest at the top of your configuration file.

/// <reference types="vitest/config" />
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  test: {
    globals: true,
    environment: 'jsdom',
  },
})

3. Use Separate Configurations for Vite and Vitest

Separating Vite and Vitest configurations can keep things clean and prevent type conflicts.

vite.config.ts

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  server: {
    port: 3000,
  },
})

vitest.config.ts

import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    globals: true,
    environment: 'jsdom',
  },
})

4. Merge Vite and Vitest Configurations

If you want to keep a single configuration file, you can merge Vite and Vitest configurations.

import { defineConfig as defineViteConfig, mergeConfig } from 'vite'
import { defineConfig as defineVitestConfig } from 'vitest/config'
import vue from '@vitejs/plugin-vue'

const viteConfig = defineViteConfig({
  plugins: [vue()],
})

const vitestConfig = defineVitestConfig({
  test: {
    globals: true,
    environment: 'jsdom',
  },
})

export default mergeConfig(viteConfig, vitestConfig)

5. Add Type Augmentation

For advanced users, you can augment Vite's UserConfig type to include the test property.

import type { UserConfig } from 'vite'
import { defineConfig } from 'vite'

declare module 'vite' {
  export interface UserConfig {
    test?: {
      globals: boolean
      environment: string
    }
  }
}

export default defineConfig({
  test: {
    globals: true,
    environment: 'jsdom',
  },
})

FAQs

Why Does This Error Occur?

The error occurs because Vite's default configuration does not include the test field. Vitest extends Vite's configuration, so the test field is only recognized when using the correct type or import.

Which Solution Should I Use?

The recommended solution is to use vitest/config for simplicity and compatibility. However, if you prefer separate configuration files, that is also a good approach.

How Do I Ensure Compatibility?

Ensure that you are using compatible versions of Vite and Vitest. Check the documentation or release notes for compatibility information.