How to fix 'importsNotUsedAsValues' is deprecated in favor of 'importsNotUsedAsValues' in TypeScript

TypeScriptINTERMEDIATELOWUpdated Dec 10, 2025· 142 views

This TypeScript warning appears when using the deprecated 'importsNotUsedAsValues' compiler option, which has been replaced by 'verbatimModuleSyntax' in TypeScript 5.0+. The fix involves updating your tsconfig.json to use the new option and adjusting your import statements to use explicit type-only imports.

Quick fix

Fixes 'importsNotUsedAsValues' is deprecated in favor of 'importsNotUsedAsValues'

// OLD - deprecated
{
  "compilerOptions": {
    "importsNotUsedAsValues": "preserve"
  }
}

// NEW - use verbatimModuleSyntax instead
{
  "compilerOptions": {
    "verbatimModuleSyntax": true
  }
}
  1. Update tsconfig.json to use verbatimModuleSyntax
  2. Update import statements to use explicit type-only imports
  3. Handle mixed value and type imports
  4. Update export statements for type-only exports
typescript — error
// OLD - deprecated
{
"compilerOptions": {
"importsNotUsedAsValues": "preserve"
}
}
// NEW - use verbatimModuleSyntax instead
{
"compilerOptions": {
"verbatimModuleSyntax": true
}
}
'importsNotUsedAsValues' is deprecated in favor of 'importsNotUsedAsValues'

What this error means

The "importsNotUsedAsValues is deprecated" warning indicates you're using an outdated TypeScript compiler option that controls how imports are handled when they only reference types. This option was deprecated in TypeScript 5.0 in favor of the newer, more consistent 'verbatimModuleSyntax' option. The 'importsNotUsedAsValues' flag had three modes: 1. **remove** (default): Drop import statements that only reference types 2. **preserve**: Keep all import statements even if values/types are never used 3. **error**: Keep all imports but error when a value import is only used as a type The new 'verbatimModuleSyntax' provides clearer rules: imports/exports without 'type' modifier are preserved, while anything with 'type' modifier is dropped entirely. This makes the behavior more predictable and aligns better with modern JavaScript tooling. You'll see this warning when: - Your tsconfig.json still contains 'importsNotUsedAsValues' - You're using TypeScript 5.0 or newer - The compiler detects the deprecated option during compilation

Typical symptoms

  • TypeScript compiler shows warning: 'importsNotUsedAsValues' is deprecated in favor of 'verbatimModuleSyntax'
  • Build logs contain deprecation warnings about the compiler option
  • IDE may show warnings in tsconfig.json file
  • The warning appears regardless of the value set for importsNotUsedAsValues
  • Code compiles successfully but with deprecation warnings
  • Newer TypeScript features may not work optimally with the deprecated option

Common causes

  1. Using TypeScript 5.0+ with tsconfig.json containing the deprecated 'importsNotUsedAsValues' option
  2. Upgrading TypeScript without updating tsconfig.json configuration
  3. Copying tsconfig.json from older projects or examples
  4. Using build tools or frameworks that haven't updated their TypeScript configuration templates
  5. The project was set up before TypeScript 5.0 was released
  6. Mixing TypeScript versions across dependencies (some use old, some use new)

How to fix "'importsNotUsedAsValues' is deprecated in favor of 'importsNotUsedAsValues'"

1Update tsconfig.json to use verbatimModuleSyntax

Replace the deprecated 'importsNotUsedAsValues' option with 'verbatimModuleSyntax' in your tsconfig.json:

json
// OLD - deprecated
{
  "compilerOptions": {
    "importsNotUsedAsValues": "preserve"
  }
}

// NEW - use verbatimModuleSyntax instead
{
  "compilerOptions": {
    "verbatimModuleSyntax": true
  }
}

If you were using 'importsNotUsedAsValues: "remove"' (the default), you can simply remove the option entirely, as TypeScript's default behavior is similar.

If you were using 'importsNotUsedAsValues: "error"', you should use 'verbatimModuleSyntax: true' and ensure your imports use explicit 'type' modifiers when needed.

2Update import statements to use explicit type-only imports

With 'verbatimModuleSyntax', you need to be explicit about type-only imports. Update your code:

typescript
// OLD - TypeScript inferred this was type-only
import { User } from "./types";
const user: User = { name: "John" };

// NEW - Add explicit 'type' modifier
import { type User } from "./types";
const user: User = { name: "John" };

// OLD - Mixed import
import { User, getUser } from "./api";

// NEW - Separate value and type imports
import { getUser } from "./api";
import { type User } from "./api";

// OLD - Namespace import for types
import * as Types from "./types";
const user: Types.User = { name: "John" };

// NEW - Use 'import type' for namespace imports
import type * as Types from "./types";
const user: Types.User = { name: "John" };

Key changes:
- Add 'type' modifier before type-only imports: import { type User }
- Use 'import type' for namespace imports of types: import type * as Types
- Keep regular imports for values: import { getUser }

3Handle mixed value and type imports

When importing both values and types from the same module, separate them or use inline type modifiers:

typescript
// OPTION 1: Separate imports (clearer)
import { getUser, updateUser } from "./api";
import { type User, type UserPreferences } from "./api";

// OPTION 2: Inline type modifiers (more concise)
import { getUser, updateUser, type User, type UserPreferences } from "./api";

// OPTION 3: Namespace import with type modifier
import { getUser, updateUser } from "./api";
import type { User, UserPreferences } from "./api";

// WRONG - This will be removed at runtime with verbatimModuleSyntax
import { User, getUser } from "./api";
// User is a type, so the import will be dropped, breaking getUser

The rule is simple: if something is only used as a type, it needs a 'type' modifier or 'import type' statement.

4Update export statements for type-only exports

The same rules apply to exports. Update type-only exports:

typescript
// OLD - TypeScript inferred this was type-only
export { User } from "./types";

// NEW - Add explicit 'type' modifier
export { type User } from "./types";

// OLD - Mixed export
export { User, createUser } from "./api";

// NEW - Separate or use inline type modifiers
export { createUser, type User } from "./api";

// OLD - Re-exporting types
export * from "./types";

// NEW - Use 'export type' for type-only re-exports
export type * from "./types";
// OR export specific types
export type { User, Product } from "./types";

Important: With 'verbatimModuleSyntax', re-exporting everything (export * from "./types") will fail if the module contains both types and values. Use export type * for type-only modules.

5Test your changes and handle edge cases

After updating, test your build:

bash
# Run TypeScript compiler
npx tsc --noEmit

# Or run your build command
npm run build

Common issues to check:

1. Missing runtime imports: If a value import was incorrectly marked as type-only:

typescript
// WRONG - getUser is a value, not a type
import { type getUser } from "./api";
const user = getUser(); // Error: getUser is not defined at runtime

// CORRECT
import { getUser } from "./api";
const user = getUser();

2. Third-party libraries: Some libraries may need @types updates:

bash
npm install --save-dev @types/library-name

3. Build tool integration: Ensure your bundler (webpack, Vite, etc.) handles the new import syntax correctly.

4. IDE support: Restart your TypeScript language server in VS Code (Cmd/Ctrl + Shift + P → "TypeScript: Restart TS Server").

6Update related configuration files

Check other configuration files that might reference the deprecated option:

1. ESLint configuration:

json
// .eslintrc.json
{
  "rules": {
    "@typescript-eslint/consistent-type-imports": "error"
  }
}

2. Babel configuration (if using Babel with TypeScript):

json
// babel.config.json
{
  "presets": [
    ["@babel/preset-typescript", {
      "onlyRemoveTypeImports": true
    }]
  ]
}

3. Framework-specific configs (Next.js, Nuxt, etc.):

javascript
// next.config.js
module.exports = {
  experimental: {
    typedRoutes: true
  }
};

4. Monorepo configurations: Update all package.json and tsconfig.json files in your monorepo.

5. CI/CD pipelines: Ensure your build scripts use the updated TypeScript version and configuration.

Advanced notes

### Migration Strategies for Large Codebases

For large projects, migrate incrementally:

1. Enable both options temporarily:

json
{
  "compilerOptions": {
    "verbatimModuleSyntax": true,
    "importsNotUsedAsValues": "preserve"
  }
}

TypeScript will use 'verbatimModuleSyntax' but keep the old behavior as fallback.

2. Use ESLint to enforce type-only imports:

bash
npm install --save-dev @typescript-eslint/eslint-plugin
json
// .eslintrc.json
{
  "plugins": ["@typescript-eslint"],
  "rules": {
    "@typescript-eslint/consistent-type-imports": [
      "error",
      {
        "prefer": "type-imports",
        "disallowTypeAnnotations": false
      }
    ]
  }
}

3. Automated migration with codemods:

bash
# Using jscodeshift
npx jscodeshift -t https://example.com/type-imports-codemod.ts src/

### Understanding the Differences

importsNotUsedAsValues: "preserve":
- Keeps all imports in output JavaScript
- TypeScript removes type references at compile time
- Can lead to unused imports in bundle

verbatimModuleSyntax: true:
- Drops imports with 'type' modifier
- Preserves imports without 'type' modifier
- What you write is what you get in output
- More predictable for bundlers

### Compatibility with Build Tools

Webpack: Works natively with verbatimModuleSyntax
Vite/esbuild: Handle type-only imports correctly
Babel: Requires 'onlyRemoveTypeImports: true' in @babel/preset-typescript
SWC: Native support for TypeScript type-only imports

### TypeScript Version Support

- TypeScript 4.5+: Introduced inline 'type' modifiers
- TypeScript 5.0+: Introduced 'verbatimModuleSyntax', deprecated 'importsNotUsedAsValues'
- TypeScript 5.3+: Improved error messages for migration

### Common Pitfalls

1. Circular type dependencies: May need to restructure when using explicit type imports
2. Dynamic imports: import() expressions work the same
3. Conditional types: Type-only imports work with conditional types
4. Mapped types: No changes needed for type-only usage in mapped types

### Performance Implications

'verbatimModuleSyntax' can improve:
- Compilation speed: Clearer rules mean less analysis
- Bundle size: Unused type imports are removed
- Tree-shaking: Bundlers can better identify unused code

### Testing After Migration

Run comprehensive tests:

bash
# Type checking
npx tsc --noEmit

# Unit tests
npm test

# Integration tests
npm run test:integration

# Build verification
npm run build && node dist/index.js

Frequently asked questions

What does "'importsNotUsedAsValues' is deprecated in favor of 'importsNotUsedAsVa" mean?
The "importsNotUsedAsValues is deprecated" warning indicates you're using an outdated TypeScript compiler option that controls how imports are handled when they only reference types. 0 in favor of the newer, more consistent 'verbatimModuleSyntax' option. The 'importsNotUsedAsValues' flag had three modes: 1.
How do I fix "'importsNotUsedAsValues' is deprecated in favor of 'importsNotUsedAsVa"?
This TypeScript warning appears when using the deprecated 'importsNotUsedAsValues' compiler option, which has been replaced by 'verbatimModuleSyntax' in TypeScript 5.0+. The fix involves updating your tsconfig.json to use the new option and adjusting your import statements to use explicit type-only imports.
What causes "'importsNotUsedAsValues' is deprecated in favor of 'importsNotUsedAsVa"?
Using TypeScript 5.0+ with tsconfig.json containing the deprecated 'importsNotUsedAsValues' option Upgrading TypeScript without updating tsconfig.json configuration Copying tsconfig.json from older projects or examples
Is the "'importsNotUsedAsValues' is deprecated in favor of 'importsNotUsedAsVa" error serious?
It is a low-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading