How to Use @typescript-eslint/no-unused-vars?

While working on TypeScript projects, I often ran into issues with unused variables referred to multiple times in the code. To solve this, I started using the @typescript-eslint/no-unused-vars rule.

The @typescript-eslint/no-unused-vars rule is used for keeping code clean and efficient. It helps identify variables that are declared but never used in your code.

In this TypeScript tutorial, I’ll explain everything you need to know about this essential ESLint rule, how to configure it for your projects, and the different options available to customize its behavior.

What is @typescript-eslint/no-unused-vars?

The @typescript-eslint/no-unused-vars rule is an extension of ESLint’s core no-unused-vars rule, specifically designed for TypeScript projects. It adds support for TypeScript features, such as types, interfaces, and other TypeScript-specific constructs.

This rule helps detect:

  • Unused variables
  • Unused function parameters
  • Unused imports
  • Unused TypeScript types and interfaces

When an unused variable is detected, ESLint will either warn you or throw an error (depending on your configuration).

Check out: Convert JSON to TypeScript Interface

Setting Up @typescript-eslint/no-unused-vars

Method 1: Basic Setup with Default Options

The simplest way to use this rule is to enable it in your ESLint configuration file. Here’s how I typically set it up:

  1. First, make sure you have ESLint and typescript-eslint installed:
npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
  1. Create or update your .eslintrc.js file:
module.exports = {
  parser: '@typescript-eslint/parser',
  plugins: ['@typescript-eslint'],
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended',
  ],
  rules: {
    '@typescript-eslint/no-unused-vars': 'error'
  }
};

Output:

TypeScript eslint variables

With this basic setup, ESLint will report all unused variables as errors. I like this strict approach because it forces me to clean up my code before committing.

Method 2: Customizing the Rule

One thing I’ve learned over the years is that the default configuration doesn’t always work for every project. Thankfully, this rule offers several customization options.

Here’s how I typically configure it for larger projects:

module.exports = {
  // other config...
  rules: {
    '@typescript-eslint/no-unused-vars': [
      'warn',
      {
        'vars': 'all',
        'args': 'after-used',
        'ignoreRestSiblings': true,
        'argsIgnorePattern': '^_',
        'varsIgnorePattern': '^_',
      }
    ]
  }
};

Let me explain each option:

  • warn‘ – Shows warnings instead of errors (useful during development)
  • vars‘: ‘all‘ – Check all variables for usage
  • args‘: ‘after-used‘ – Only warn about unused function parameters if they come after a used parameter
  • ignoreRestSiblings‘: true – Ignore variables that are part of object destructuring with rest properties
  • argsIgnorePattern‘: ‘^_‘ – Ignore parameters that start with an underscore
  • varsIgnorePattern‘: ‘^_‘ – Ignore variables that start with an underscore

Output:

eslint unused variables in TypeScript

This configuration gives me the flexibility I need for real-world projects while still keeping my code clean.

Check out:  Set Default Values in TypeScript Interfaces

Using Prefix Patterns to Ignore Variables

Sometimes, we deliberately have unused variables that we want ESLint to ignore. A common convention I use is prefixing these variables with an underscore.

First, create or update the file eslint.config.js.

import js from '@eslint/js';
import tseslint from 'typescript-eslint';

export default [
  js.configs.recommended,
  ...tseslint.configs.recommended,
  {
    rules: {
      '@typescript-eslint/no-unused-vars': [
        'warn',
        {
          vars: 'all',
          args: 'after-used',
          ignoreRestSiblings: true,
          argsIgnorePattern: '^_',
          varsIgnorePattern: '^_',
        },
      ],
    },
  },
];

For example, in React components, where you might destructure props but not use all of them:

interface UserProps {
  name: string;
  age: number;
  address: string;
}

// Only using name and age — not using address
function UserCard({ name, age, _address }: UserProps) {
  return (
    <div>
      <h2>{name}</h2>
      <p>Age: {age}</p>
      {/* _address is intentionally unused */}
    </div>
  );
}

Output:

Ignore unused variables in TypeScript

With the argsIgnorePattern set to ^_, ESLint won’t complain about the unused _address parameter.

This approach is popular among TypeScript developers as it clearly communicates intent while avoiding linting errors.

Check out:  Convert JSON to TypeScript Interface

Working with Callbacks and Higher-Order Functions

When working with callbacks and higher-order functions, you’ll often have parameters that you don’t use but need to include due to the function signature.

Here’s how I handle this:

// API expects a callback with error and result parameters
fetchUserData((error, result) => {
  // We only care about the result, not the error
  if (error) {
    return;
  }

  console.log(result);
});

In this case, ESLint would complain that error is declared but never used. To handle this situation, I use one of two approaches:

1. Use the Underscore Prefix:

fetchUserData((_error, result) => {
  console.log(result);
});

2. Selectively disable the rule for specific lines:

fetchUserData((
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  error, 
  result
) => {
  console.log(result);
});

Check out:  Remove a Property from an Object in TypeScript

Using with TypeScript Compiler Options

I’ve found that combining this ESLint rule with TypeScript’s compiler options provides the most comprehensive coverage. In your tsconfig.json:

{
  "compilerOptions": {
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    // other options...
  }
}

Handling Special Cases

Destructuring with Rest Operators

When destructuring objects, the ignoreRestSiblings option comes in handy:

const { id, name, ...rest } = user;
console.log(id); // Only using id

// With ignoreRestSiblings: true, ESLint won't complain about 
// the unused 'name' variable because it's followed by a rest operator

Function Parameters in Interfaces or Abstract Classes

For interfaces or abstract classes where function parameters are defined but not used in the implementation:

interface DataProcessor {
  process(data: string, options: Options): void;
}

class SimpleProcessor implements DataProcessor {
  process(data: string, _options: Options): void {
    // We don't use options in this implementation
    console.log(data.toUpperCase());
  }
}

Temporarily Disabling the Rule

Sometimes during development, I need to temporarily disable this rule. Here’s how I do it:

For a specific line:

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const tempVariable = calculateSomething();

For a block of code:

/* eslint-disable @typescript-eslint/no-unused-vars */
const step1 = performStepOne();
const step2 = performStepTwo();
const step3 = performStepThree();
/* eslint-enable @typescript-eslint/no-unused-vars */

For an entire file:

/* eslint-disable @typescript-eslint/no-unused-vars */
// Code here...

Check out: Nullish Coalescing (??) vs Logical OR (||) Operator in TypeScript

Common Issues and Solutions

False Positives with TypeScript Types

Sometimes, TypeScript types that appear unused are actually being used for type checking. In these cases, you might want to selectively disable the rule for type definitions:

// eslint-disable-next-line @typescript-eslint/no-unused-vars
type APIResponse<T = any> = {
  data: T;
  status: number;
};

Handling React Components

When working with React components, you might encounter situations where props are extracted but not directly used:

function ProfileCard({ user, onUpdate }) {
  // user is only passed to another component
  return <UserDisplay user={user} />;
}

In such cases, I often use the destructuring approach with clear variable names rather than disabling the rule.

The @typescript-eslint/no-unused-vars rule is an essential tool for maintaining clean, efficient TypeScript code. By properly configuring it according to your project’s needs, you can catch potential issues early and ensure your codebase remains maintainable.

I’ve found that the effort invested in setting up this rule pays off immensely in the long run, especially for larger projects with multiple developers. Not only does it help catch bugs, but it also enforces good coding practices across the team.

Remember that the best configuration is the one that fits your specific project needs. Don’t be afraid to experiment with different options until you find the right balance between strictness and practicality.

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.