This TypeScript/ESLint warning appears when you destructure variables from an object or array but never use those variables in your code. The fix involves either using the destructured variables, removing them, or marking them as intentionally unused with an underscore prefix.
This warning is emitted by ESLint's `no-unused-vars` rule (or its TypeScript variant `@typescript-eslint/no-unused-vars`) when it detects that you've destructured elements from an object or array but haven't used any of them in your code. Destructuring is a JavaScript/TypeScript feature that extracts values from objects or arrays into individual variables. When you destructure but don't use the variables, it's typically a mistake—either you forgot to use them, or you're accessing the parent object directly instead of the destructured variables. This warning helps catch bugs early. For example, if you write `const { max, min } = stats` but then use `stats.max` instead of `max`, you're creating unnecessary variables and potentially using the wrong reference. The linter warns you so you can either fix the code or remove the unused destructuring.
If you destructured variables but are still accessing the parent object, replace those accesses with the destructured variables:
// WRONG - destructured but not using them
const half = ({ max, min }) => {
return (stats.max + stats.min) / 2.0; // Using stats instead of max/min
};
// CORRECT - use the destructured variables
const half = ({ max, min }) => {
return (max + min) / 2.0;
};Another example with object destructuring:
// WRONG
const { name, age } = user;
console.log(user.name, user.age); // Not using destructured variables
// CORRECT
const { name, age } = user;
console.log(name, age); // Using destructured variablesIf you genuinely don't need the destructured variables, remove the destructuring assignment:
// WRONG - unnecessary destructuring
const { id, name } = user;
await saveUser(user);
// CORRECT - just use the object directly
await saveUser(user);For array destructuring:
// WRONG
const [first, second] = items;
console.log(items);
// CORRECT
console.log(items);If you need to destructure some variables but intentionally don't use certain ones, prefix them with an underscore:
// Skip first element but keep second
const [_unused, needed] = array;
console.log(needed);
// Extract some properties, ignore others
const { _id, name, email } = user;
console.log(name, email); // Not using _idConfigure ESLint to allow this pattern in your .eslintrc.json or eslint.config.js:
{
"rules": {
"@typescript-eslint/no-unused-vars": [
"error",
{
"varsIgnorePattern": "^_",
"destructuredArrayIgnorePattern": "^_"
}
]
}
}For arrays, you can skip elements by leaving empty slots in the destructuring pattern:
// Skip first element entirely (no variable created)
const [, second, third] = items;
console.log(second, third);
// Skip middle elements
const [first, , , fourth] = items;
console.log(first, fourth);This is cleaner than using underscore-prefixed names when you genuinely don't need certain positional elements.
When you want to extract certain properties while keeping the rest, use the rest operator and configure ignoreRestSiblings:
// Extract date, keep everything else
const { date, ...rest } = payload;
processData(rest); // Only using rest, not dateConfigure ESLint to allow this pattern:
{
"rules": {
"@typescript-eslint/no-unused-vars": [
"error",
{
"ignoreRestSiblings": true
}
]
}
}This tells ESLint that it's okay for sibling properties to be unused when using rest patterns, because you're using them to extract/omit properties.
### ESLint Configuration Details
The @typescript-eslint/no-unused-vars rule extends ESLint's base rule and adds TypeScript-specific support. Key configuration options:
{
"rules": {
"@typescript-eslint/no-unused-vars": [
"error",
{
"vars": "all",
"args": "after-used",
"ignoreRestSiblings": true,
"varsIgnorePattern": "^_",
"argsIgnorePattern": "^_",
"destructuredArrayIgnorePattern": "^_"
}
]
}
}- ignoreRestSiblings: Allows unused variables when using rest operator to omit properties
- varsIgnorePattern: Regex pattern for variable names to always allow (e.g., ^_ for underscore prefix)
- destructuredArrayIgnorePattern: Same as varsIgnorePattern but specifically for array destructuring
### Common Pattern: Omitting Properties
A common use case for "intentionally unused" destructured variables is property omission:
// Remove password before sending user object to client
const { password, ...safeUser } = dbUser;
return res.json(safeUser);With ignoreRestSiblings: true, ESLint won't complain about unused password.
### TypeScript Type Narrowing
Sometimes destructuring is used purely for type checking or narrowing, especially in discriminated unions:
type Event =
| { type: "click"; x: number; y: number }
| { type: "keypress"; key: string };
function handle(event: Event) {
const { type } = event; // Extract for type narrowing
if (type === "click") {
// TypeScript now knows event has x, y
console.log(event.x, event.y);
}
}Here, type is extracted but might not be used directly—it's for type narrowing. You might prefix it with underscore or just disable the rule for that line:
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { type } = event;### Avoiding Over-Suppression
While underscore prefixes and ESLint configuration are useful, avoid overusing them. If you have many unused variables, it might indicate:
1. Dead code: Variables that were meant to be used but aren't (bugs)
2. Incomplete refactoring: Code in transition that needs completion
3. Copy-paste errors: Copied destructuring from elsewhere without adapting it
Always question whether a variable truly needs to be "intentionally unused" or if it indicates a real issue.
Type parameter 'X' is not used in the function signature
How to fix "Type parameter not used in function signature" in TypeScript
Type parameter 'X' is defined but never used
How to fix "Type parameter is defined but never used" in TypeScript
Function expression requires a return type
Function expression requires a return type
Value of type 'string | undefined' is not iterable
How to fix "Value is not iterable" in TypeScript
Type 'undefined' is not assignable to type 'string'
How to fix "Type undefined is not assignable to type string" in TypeScript