How to fix Property 'x' is declared but never used in TypeScript

TypeScriptBEGINNERLOWUpdated Dec 11, 2025· 163 views

This TypeScript error occurs when you declare a variable, function, or class property but never reference it in your code. It's triggered by the noUnusedLocals compiler option to help maintain clean code by removing dead code and unused declarations.

Quick fix

Fixes Property 'x' is declared but never used

// Example of unused variable
const unusedVariable = "hello";  // Warning: 'unusedVariable' is declared but never used

// Ask yourself:
// 1. Is this variable part of a future feature?
// 2. Is it used in a different file (exported)?
// 3. Is it a placeholder for upcoming implementation?

// If genuinely unused, remove it:
// const unusedVariable = "hello";  // DELETE THIS LINE

// If it will be used later, you can prefix with underscore to suppress warning:
const _unusedVariable = "hello";  // No warning with underscore prefix
  1. Check if the declaration is actually needed
  2. Remove unused imports
  3. Use underscore prefix for intentionally unused parameters
  4. Configure tsconfig.json noUnusedLocals option
typescript — error
// Example of unused variable
const unusedVariable = "hello"; // Warning: 'unusedVariable' is declared but never used
// Ask yourself:
// 1. Is this variable part of a future feature?
// 2. Is it used in a different file (exported)?
// 3. Is it a placeholder for upcoming implementation?
// If genuinely unused, remove it:
// const unusedVariable = "hello"; // DELETE THIS LINE
// If it will be used later, you can prefix with underscore to suppress warning:
const _unusedVariable = "hello"; // No warning with underscore prefix
Property 'x' is declared but never used

What this error means

The "Property is declared but never used" error is a TypeScript compiler warning that appears when you have the `noUnusedLocals` option enabled in your tsconfig.json. This feature helps identify code that is declared but never actually used, which can indicate: 1. **Dead code**: Variables or functions that were written but never called 2. **Unused imports**: Import statements that bring in modules you don't use 3. **Leftover code**: Code from previous implementations that wasn't cleaned up 4. **Unused parameters**: Function parameters that are declared but not referenced This error doesn't prevent compilation but serves as a warning to keep your codebase clean and maintainable. It's part of TypeScript's strict mode family of checks designed to improve code quality.

Typical symptoms

  • TypeScript compiler shows warning: "Property 'x' is declared but never used"
  • IDE shows grayed-out or faded text for unused declarations
  • Build output includes warnings about unused variables or imports
  • Code compiles successfully but with warnings in the terminal
  • Unused code appears in editor with visual indicators (VS Code shows faded text)
  • Error appears for variables, functions, imports, or class properties

Common causes

  1. The `noUnusedLocals` compiler option is enabled in tsconfig.json
  2. Variables declared but never referenced in the code
  3. Functions defined but never called
  4. Import statements that bring in modules not used in the file
  5. Class properties or methods that are never accessed
  6. Parameters in function signatures that aren't used in the function body
  7. Leftover code from refactoring or feature removal
  8. Temporary variables created during debugging that weren't removed

How to fix "Property 'x' is declared but never used"

1Check if the declaration is actually needed

First, determine if the unused declaration should be kept or removed:

typescript
// Example of unused variable
const unusedVariable = "hello";  // Warning: 'unusedVariable' is declared but never used

// Ask yourself:
// 1. Is this variable part of a future feature?
// 2. Is it used in a different file (exported)?
// 3. Is it a placeholder for upcoming implementation?

// If genuinely unused, remove it:
// const unusedVariable = "hello";  // DELETE THIS LINE

// If it will be used later, you can prefix with underscore to suppress warning:
const _unusedVariable = "hello";  // No warning with underscore prefix

For functions and classes:

typescript
// Unused function
function calculateTotal() {  // Warning
  return 100;
}

// If needed for exports or future use:
export function calculateTotal() {  // No warning if exported
  return 100;
}

// Or prefix with underscore:
function _calculateTotal() {  // No warning
  return 100;
}
2Remove unused imports

Unused imports are a common cause of this warning:

typescript
// WRONG - imported but not used
import React, { useState, useEffect } from 'react';  // Warning if useState/useEffect not used

// CORRECT - only import what you need
import React from 'react';

// If you need them later:
import React from 'react';
// import { useState, useEffect } from 'react';  // Comment out until needed

// Using a linter or IDE can help:
// In VS Code: Right-click → "Organize Imports" (Ctrl+Shift+O)
// This automatically removes unused imports

// For type-only imports that shouldn't trigger warnings:
import type { User } from './types';  // Type-only imports don't count as unused

Most modern IDEs can automatically remove unused imports. In VS Code:
1. Open the command palette (Ctrl+Shift+P)
2. Type "Organize Imports"
3. Select the command to clean up imports

3Use underscore prefix for intentionally unused parameters

For function parameters that must exist in the signature but aren't used:

typescript
// WRONG - unused parameter triggers warning
function handleClick(event: MouseEvent) {
  console.log('Clicked!');
  // 'event' parameter not used - warning
}

// CORRECT - prefix with underscore
function handleClick(_event: MouseEvent) {
  console.log('Clicked!');
  // No warning with underscore prefix
}

// For multiple unused parameters:
function fetchData(_url: string, _options: RequestInit, callback: (data: any) => void) {
  // Only callback is used, url and options are intentionally unused
  callback({});
}

// For destructuring with unused properties:
const { usedProp, _unusedProp } = someObject;  // Prefix unused destructured properties

// In try-catch where error might not be used:
try {
  riskyOperation();
} catch (_error) {  // Prefix if error not used
  console.log('Operation failed');
}

The underscore convention tells TypeScript (and other developers) that the parameter is intentionally unused.

4Configure tsconfig.json noUnusedLocals option

Control the strictness of this check in your TypeScript configuration:

json
// tsconfig.json
{
  "compilerOptions": {
    // Strict mode options (all enabled by default in strict mode)
    "noUnusedLocals": true,      // Check for unused local variables
    "noUnusedParameters": true,  // Check for unused function parameters
    "noImplicitReturns": true,   // All code paths must return a value

    // Alternative: Use strict mode which includes these
    "strict": true  // Enables all strict type-checking options
  }
}

To disable the warning (not recommended for production code):

json
{
  "compilerOptions": {
    "noUnusedLocals": false,     // Disable unused locals check
    "noUnusedParameters": false  // Disable unused parameters check
  }
}

For specific files only (using comments):

typescript
// @ts-nocheck - Disable all checks for this file
// or
// @ts-ignore - Disable next line
const unused = "test";  // @ts-ignore

However, disabling these checks reduces code quality benefits.

5Use ESLint with TypeScript for better unused code detection

ESLint provides more granular control over unused code detection:

bash
# Install ESLint with TypeScript support
npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin

Create .eslintrc.js:

javascript
module.exports = {
  parser: '@typescript-eslint/parser',
  plugins: ['@typescript-eslint'],
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended'
  ],
  rules: {
    '@typescript-eslint/no-unused-vars': ['warn', {
      'argsIgnorePattern': '^_',
      'varsIgnorePattern': '^_',
      'caughtErrorsIgnorePattern': '^_'
    }],
    'no-unused-vars': 'off' // Turn off base rule in favor of TypeScript rule
  }
};

ESLint advantages over TypeScript's noUnusedLocals:
- More configurable ignore patterns
- Can be warnings vs errors
- Better editor integration
- Fixable with --fix flag

Run ESLint to find and fix unused code:

bash
npx eslint src/ --fix
6Handle edge cases and false positives

Some patterns look like unused code but are actually used:

typescript
// 1. Destructuring with rest operator
const { used, ...rest } = obj;  // 'rest' might appear unused but is valid

// 2. Functions used as types
type Handler = (event: Event) => void;
const onClick: Handler = (event) => {  // 'event' appears unused but is part of type
  console.log('clicked');
};

// 3. Module augmentation
declare global {
  interface Window {
    myCustomProp: string;  // Augmentation, not direct usage
  }
}

// 4. Side-effect imports
import './styles.css';  // Import for side effects, no named imports
import 'polyfill';      // Polyfill that modifies global scope

// 5. Re-export patterns
export { Button } from './Button';  // Re-export, Button not "used" in this file

// 6. Generic type parameters
function identity<T>(value: T): T {  // T might appear unused in simple cases
  return value;
}

// 7. Decorator parameters
function Log(target: any, key: string) {  // Parameters used by decorator system
  // target and key might not be referenced in body
}

// For these cases, use ignore comments or underscore prefix:
import './styles.css';  // OK - side effect import
const { used, ..._rest } = obj;  // Prefix if rest truly unused

Advanced notes

### noUnusedLocals vs noUnusedParameters

TypeScript has two related options:
- noUnusedLocals: Checks for unused local variables, functions, classes, imports, etc.
- noUnusedParameters: Specifically checks for unused function parameters

Both are included when strict: true is set.

### Performance Implications

The unused code checks have minimal performance impact during compilation. However, they can significantly improve:
- Bundle size: Removing unused code reduces final bundle size
- Maintainability: Cleaner code is easier to understand and modify
- Runtime performance: Less code to parse and execute

### Integration with Build Tools

Webpack: Use TerserPlugin for dead code elimination in production:

javascript
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
  optimization: {
    minimize: true,
    minimizer: [new TerserPlugin()],
  },
};

Vite: Uses esbuild which performs tree-shaking automatically.

Rollup: Has built-in tree-shaking; unused exports are removed.

### Type-Only Imports

TypeScript 3.8+ introduced type-only imports that don't count as "used" for noUnusedLocals:

typescript
import type { User, Product } from './types';  // Type-only, no runtime import
import { createUser } from './api';           // Value import

// Mixed import (TypeScript 4.5+):
import { type User, createUser } from './api';

### Migration Strategy

When enabling noUnusedLocals on an existing codebase:
1. Enable as warning first: "noUnusedLocals": true
2. Use // @ts-ignore comments temporarily
3. Gradually fix warnings file by file
4. Consider using ESLint's --fix option for bulk fixes
5. Once clean, consider making it an error: "noUnusedLocals": "error" in ESLint

### False Positives in Test Files

Test files often have setup code that appears unused:

typescript
// In Jest/Vitest test files
describe('MyComponent', () => {
  it('should render', () => {
    // Test code
  });
});

// The describe and it functions might trigger unused warnings
// Solution: Configure ESLint/TypeScript to ignore test files

Create a separate tsconfig for tests:

json
// tsconfig.test.json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "noUnusedLocals": false,
    "noUnusedParameters": false
  }
}

Frequently asked questions

What does "Property 'x' is declared but never used" mean?
json. This feature helps identify code that is declared but never actually used, which can indicate: 1. Dead code: Variables or functions that were written but never called 2.
How do I fix "Property 'x' is declared but never used"?
This TypeScript error occurs when you declare a variable, function, or class property but never reference it in your code. It's triggered by the noUnusedLocals compiler option to help maintain clean code by removing dead code and unused declarations.
What causes "Property 'x' is declared but never used"?
The noUnusedLocals compiler option is enabled in tsconfig.json Variables declared but never referenced in the code Functions defined but never called
Is the "Property 'x' is declared but never used" error serious?
It is a low-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading