Search code examples
typescripteslinttypescript-eslint

Why doesn't ESLint complain about implicit `any` returned from function call?


Why doesn't ESLint complain about implicit any in this line:

// `serializedResult` is `any` and that's okey becauase `sendMessage(...)` return value 
// has `Promise<any>`. But why eslint doesn't complain?
const serializedResult = await browser.runtime.sendMessage(serializedPacket);

Configuration files:

// type declaration for function come from `index.d.ts`:
declare namespace browser.runtime
{
    ...
    function sendMessage(message: any, options?: _SendMessageOptions): Promise<any>;
    function sendMessage(extensionId: string, message: any, options?: _SendMessageOptions): Promise<any>;
    ...
}
// .eslintrc.json
{
    "env": 
    {
        "browser": true,
        "es2021": true
    },
    "extends": 
    [
        "eslint:recommended",
        "plugin:@typescript-eslint/recommended"
    ],
    "parser": "@typescript-eslint/parser",
    "parserOptions": 
    {
        "ecmaVersion": "latest",
        "sourceType": "module"
    },
    "ignorePatterns": 
    [
        "bin/**"
    ],
    "plugins": 
    [
        "@typescript-eslint"
    ],
    "rules": 
    {
        "prefer-rest-params": "off",
        "@typescript-eslint/no-explicit-any": "error"
    }
}

// tsconfig.json
{
    "compilerOptions":
    {
        "target": "es2022",
        "module": "NodeNext",
        "moduleResolution": "NodeNext",
        
        "strict": true,
        "noImplicitAny": true,
        "esModuleInterop": true,
        "skipLibCheck": true,
        "forceConsistentCasingInFileNames": true,
        "sourceMap": true
    }
}

Am I missing something? Should this work?


Solution

  • There are two tools in play here:

    • ESLint (a linter): runs a configurable list of rules. Each lint rule checks for one particular problem and might report on instances of the problem it finds.
    • TypeScript (a language): lets you write code in a syntax that includes all of JavaScript plus some new constructs for types. It includes a type checker that warns you if some code has mismatched types.

    TypeScript's noImplicitAny compiler option only complains about parameters and variables whose type cannot be inferred. If something is known to be type any and assigned to some variable, that's a wholly separate issue. It's not an "implicit" any.

    What you're looking for is a lint rule that can find places in code that have an any. There are a few lint rules in typescript-eslint (the parser & ESLint plugin that add TypeScript support and TypeScript-specific rules to ESLint):

    Those rules are all lint rules that require linting with type information because they require using TypeScript APIs to determine the types of things. In this case, they'd need to use type information to know which values are any.

    Your ESLint config isn't enabling those rules because it's only set to extend from "plugin:@typescript-eslint/recommended", which doesn't enable lint rules that require type checking. "plugin:@typescript-eslint/recommended-type-checked" does that. You can read more about the preset typescript-eslint configs on typescript-eslint.io/linting/configs.