TS7006

Parameter 'x' implicitly has an 'any' type

๐Ÿ“š Difficulty: Beginner โฑ๏ธ 4 min read ๐Ÿ”„ Updated: Feb 2025

What is TS7006?

TS7006 occurs when TypeScript cannot infer the type of a function parameter and the noImplicitAny compiler option is enabled. This forces you to explicitly declare types, preventing accidental use of any.

// Example of TS7006 error
function greet(name) { // Error: Parameter 'name' implicitly has an 'any' type
    console.log(`Hello, ${name}!`);
}

Why Does This Error Exist?

The noImplicitAny option (enabled by default with strict: true) ensures type safety by requiring explicit type annotations. Without this, TypeScript would silently treat untyped parameters as any, defeating the purpose of type checking.

Common Causes

1. Untyped Function Parameters

// โŒ No type annotation
function add(a, b) { // Error on both 'a' and 'b'
    return a + b;
}

// โœ… Add type annotations
function add(a: number, b: number): number {
    return a + b;
}

2. Arrow Functions

// โŒ Untyped arrow function
const double = (n) => n * 2; // Error!

// โœ… Add type annotation
const double = (n: number): number => n * 2;

3. Callback Functions

// โŒ Callback without types
[1, 2, 3].forEach((item) => { // Usually OK due to inference
    console.log(item);
});

// โŒ But standalone callbacks need types
const callback = (item) => { // Error!
    console.log(item);
};

4. Event Handlers

// โŒ Event handler without type
function handleClick(event) { // Error!
    console.log(event.target);
}

// โœ… Add proper event type
function handleClick(event: MouseEvent) {
    console.log(event.target);
}

Solutions

1. Add Type Annotations

// Basic types
function greet(name: string): void {
    console.log(`Hello, ${name}!`);
}

// Object types
function processUser(user: { name: string; age: number }) {
    console.log(user.name, user.age);
}

// Array types
function sumNumbers(numbers: number[]): number {
    return numbers.reduce((a, b) => a + b, 0);
}

2. Use Interfaces or Type Aliases

interface User {
    name: string;
    email: string;
}

function sendEmail(user: User, message: string): void {
    // Implementation
}

// Or with type alias
type Callback = (value: string) => void;

function processAsync(callback: Callback): void {
    callback('result');
}

3. Use Generics

// โœ… Generic function
function identity<T>(value: T): T {
    return value;
}

// โœ… Generic arrow function
const toArray = <T>(value: T): T[] => [value];

4. Explicit 'any' (Last Resort)

// โœ… If you truly need any, be explicit
function logAnything(value: any): void {
    console.log(value);
}

// Better: use 'unknown' for safer any-like behavior
function processUnknown(value: unknown): void {
    if (typeof value === 'string') {
        console.log(value.toUpperCase());
    }
}

๐Ÿ’ก Pro Tip

Prefer unknown over any when you don't know the type. It provides type safety by requiring type checks before use.

Real-World Examples

React Event Handlers

// โŒ Untyped event
const handleChange = (e) => { // Error!
    console.log(e.target.value);
};

// โœ… Properly typed
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    console.log(e.target.value);
};

// โœ… Alternative with inline annotation
<input onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
    console.log(e.target.value);
}} />

Express.js Route Handlers

import { Request, Response } from 'express';

// โŒ Untyped
app.get('/users', (req, res) => { // Error!
    res.json({ users: [] });
});

// โœ… Properly typed
app.get('/users', (req: Request, res: Response) => {
    res.json({ users: [] });
});

Utility Functions

// โŒ Untyped utility
const debounce = (fn, delay) => { // Error!
    let timeoutId;
    return (...args) => {
        clearTimeout(timeoutId);
        timeoutId = setTimeout(() => fn(...args), delay);
    };
};

// โœ… Properly typed
const debounce = <T extends (...args: any[]) => any>(
    fn: T,
    delay: number
): ((...args: Parameters<T>) => void) => {
    let timeoutId: ReturnType<typeof setTimeout>;
    return (...args) => {
        clearTimeout(timeoutId);
        timeoutId = setTimeout(() => fn(...args), delay);
    };
};

โš ๏ธ Don't Disable noImplicitAny

While you can disable this check in tsconfig.json, it's strongly recommended to keep it enabled. It catches many potential bugs at compile time.

Summary

Still Confused by Your Error?

Paste your TypeScript error into our analyzer for instant, detailed explanations.

Try Error Analyzer โ†’