Skip to content

Bug: [no-unnecessary-type-parameters] Apparent false positive when type parameter is used once in function signature but is passed into a generic function signature #11528

@BernardoFuret

Description

@BernardoFuret

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.
  • I have searched for related issues and found none that matched my issue.
  • I have read the FAQ and my problem is not listed.

Playground Link

https://typescript-eslint.io/play/#ts=5.9.2&fileType=.tsx&code=JYOwLgpgTgZghgYwgAgJIFEpQPZQDwAqAInGHAHzIDeAsAFDLLQ5QBcyYUArhANz2MAJqTjtiI-nQC%2B9egmwgAzmGQIAFhAQBrVIswtkAXmSESZADTkAFHBABPMGtABzdlxBaQ2AO4gAlOy2Dk4gzsjAimj6uKYilIaUtAzIUBBgXFAgyFYCHHYADhDYMMhBji5GhsYA5NgARgBWmmDVyABkbbkAhF1lIWEdudXMuK2gpfbloe2dyWAFRSV9LgB0I1CVNXXY2AA2ELatg8nLoWtYuLl%2BklKScgrKTAAenIhg0VBmcEYm4hbW6wA-G4PF5fAFkH9vgAfZAgLi7XZGRK5VLpTKqDTaXQfWJkAEXKB%2BZCApiElbCMjIdjwxE3XhAA&eslintrc=N4KABGBEBOCuA2BTAzpAXGUFtQAIBcBPABxQGNoBLY-AWhXkoDt8B6Jge1tiacTJTIAhtEK0ipWsRFCAtonyJoqDJCXQO0SODABfELqA&tsconfig=N4KABGBEDGD2C2AHAlgGwKYCcDyiAuysAdgM6QBcYoEEkJemy0eAcgK6qoDCAFutAGsylBm3TgwAXxCSgA&tokens=false

Repro Code

interface IError<TData> {
  error: true;
  data: TData;
}

const checkIsError = <TData>(anything: unknown): anything is IError<TData> => {
  return (
    typeof anything === 'object' &&
    !!anything &&
    'error' in anything &&
    typeof anything.error === 'boolean' &&
    anything.error
  );
};

const extractErrorData = <TData>(error?: unknown): TData | null => {
  return checkIsError<TData>(error) ? error.data : null;
};

ESLint Config

module.exports = {
  parser: "@typescript-eslint/parser",
  rules: {
    "@typescript-eslint/<rule-name>": ["error", ...<options>],
  },
};

tsconfig

{
  "compilerOptions": {
    // ...
  }
}

Expected Result

I didn't expect the error on TData, because it is passed to the type guard and is needed to provide the return type of the extractErrorData function.

Actual Result

I receive an error on the generic TData of extractErrorData saying Type parameter TData is used only once in the function signature.

Additional Info

Hi,
I read the docs and I tried to search for a similar case, but didn't find any answers. My apologies if this has been covered or falls into a described case and I simply failed to understand it.

Now onto the problem:
I understand the suggestion to replace all usages of the type parameter with its constraint (unknown, in this case), but that would mean I can't type the data field of the object. I understand there's no runtime guarantee of the structure of the data field (as in: I'm not performing any checks on the structure of the data field). But from a type descriptions perspective, shouldn't it work, just like type guards do?

Then, why does the following work?

const extractErrorData = <TData,>(error?: unknown): IError<TData> | null => {
  return checkIsError<TData>(error) ? error : null;
};

Here, the returned type is IError<TData> instead of TData. The same checks are applied to TData, but there's no alert from the rule.
(Here's a playground link)

Should the rule stop alerting on my original case? Or should the rule also alert for this second case? Or am I seeing this wrong?

Any help is greatly appreciated, thank you!

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpackage: eslint-pluginIssues related to @typescript-eslint/eslint-pluginworking as intendedIssues that are closed as they are working as intended

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions