Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Enhancement: [no-unsafe-*] misses any violations on union and object types #10158

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
4 tasks done
ronami opened this issue Oct 16, 2024 · 6 comments
Closed
4 tasks done
Labels
bug Something isn't working locked due to age Please open a new issue if you'd like to say more. See https://typescript-eslint.io/contributing. package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin wontfix This will not be worked on

Comments

@ronami
Copy link
Member

ronami commented Oct 16, 2024

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.3.2&fileType=.tsx&code=PTAEDsHsFoFdwM4EMBmBTaSBOBzWBbNcAFwC4AocgEzQGMAbbNUWyRY0JU0Ab1BUiRuScAE9QAXwDclFPFrEAlm36CAFAA9ufAUNAJiWReBySAlNtV6DRk5N7lQoLGmKws4UBpkTKIUACqiKjM2HiEJKCQKKDEogAOzAAGOoLCYlKSSZwICIo44GhUsZCcoPHYSITEaFhRMXGJoClW3DbGOJkSSQB05LpqSGYy1HSMLixsBqAARumiANoAuqAAPhAEM7UjcuAKyp4z2Jpthh3Laxv4W1gW%2BmcmF%2Bvgm7UOTi5uHl4%2BfmBByHQnFwBCIHGisQSyRe1ze6xEiyW2SQuXyhWKxFKSHKlWqbwhjWhrzq63ajyRfSOWDUM2Gf30inwinG9HEAHdFMQABbNKBwYLoaCfdzgJKUGgMJiTdgsSy6eaSEZoDTxSBYDi7fYqLloej0SBqO6pawPUwSd6gfwAkLOVwi%2BqQppJBHZFBYSD4fjyJQqDnc21fTyE5pknC9RwB%2B1IX6jSUTVgyqjzJ5XG5KlVqjXeg6gNlq%2BhUQ2nWw4FMwm4Wq0C5jC74EqHNBHLV3uz2an2eP082tBhtJUPNvofO3fGY%2BIA&eslintrc=N4KABGBEBOCuA2BTAzpAXGUEKQAIBcBPABxQGNoBLY-AWhXkoDt8B6Jge1tieQEMAZolp9kySgHMmAW0Qt0URNGgdokADThseIqWQVqdBszaduvQcOiJ8saEwWQlKtVoC%2BIN0A&tsconfig=N4KABGBEDGD2C2AHAlgGwKYCcDyiAuysAdgM6QBcYoEEkJemy0eAcgK6qoDCAFutAGsylBm3TgwAXxCSgA&tokens=false

Repro Code

// no-unsafe-argument:

declare const a: { foo: any };

function foo(x: { foo: string }): { foo: string } {
  return x;
}

// Unsafe argument of type `{ foo: any; }` assigned to a parameter of type `{ foo: string; }`.
foo(a);

declare const b: any[] | number;

function bar(x: string[] | number): string[] | number {
  return x;
}

// Unsafe argument of type `number | any[]` assigned to a parameter of type `number | string[]`.
bar(b);

// similarly with `no-unsafe-return`

declare const c: { foo: any };

export function hello(): { foo: string } {
  // Unsafe return of type `{ foo: any }` from function with return type `{ foo: string }`.
  return a;
}

declare const d: any[] | number;

export function world(): string[] | number {
  // Unsafe return of type `any[]` from function with return type `number | string[]`.
  return b;
}

ESLint Config

module.exports = {
  parser: "@typescript-eslint/parser",
  rules: {
    "@typescript-eslint/no-unsafe-assignment": "error",
    "@typescript-eslint/no-unsafe-return": "error",
  },
};

tsconfig

{
  "compilerOptions": {
    "strictNullChecks": true
  }
}

Expected Result

I expected the rule to fail on these, similarly to how it fails on similar boxed values like Promise<any>, or any[], along with a combination of boxed values.

Actual Result

The code example is reporting no lint errors.

Additional Info

The no-unsafe-* rule family misses some edge case checks, mostly around boxed values (like arrays, objects, promises, etc.). While you get a warning for most any values wrapped in a box, I found some the rule misses around union and object types.

I made a simplified implementation to test-run on typescript-eslint's own repo and found one issue here (matching string[] | undefined with any[]).

@ronami ronami added bug Something isn't working package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin triage Waiting for team members to take a look labels Oct 16, 2024
@ronami ronami changed the title Enhancement: [no-unsafe-*] miss any violations on unions and objects types Enhancement: [no-unsafe-*] misses any violations on unions and objects types Oct 16, 2024
@ronami ronami changed the title Enhancement: [no-unsafe-*] misses any violations on unions and objects types Enhancement: [no-unsafe-*] misses any violations on union and object types Oct 16, 2024
@ronami
Copy link
Member Author

ronami commented Nov 3, 2024

Adding that functions are also being missed:

declare const onSomething: (callback: () => number) => void;
declare const callback: () => any;

// no lint errors
onSomething(callback);

@bradzacher
Copy link
Member

The rules currently do not recurse into cases like arguments, return types, or sub-union members - for complexity reasons on the initial implementation and generally these cases are caught at the declaration site.

Eg the return type issue should be handled at the function declaration via no-unsafe-return. The argument issue (or technically any of these issues) is caught by no-explicit-any.

Usually the only time you'd be dealing with such cases like these is if an external library type has given them to you.

Do you have a real-world example of this that a combination of all of the current no-unsafe rules plus no-explicit-any wouldn't handle?

@ronami
Copy link
Member Author

ronami commented Nov 4, 2024

The rules currently do not recurse into cases like arguments, return types, or sub-union members - for complexity reasons on the initial implementation and generally these cases are caught at the declaration site.

Eg the return type issue should be handled at the function declaration via no-unsafe-return. The argument issue (or technically any of these issues) is caught by no-explicit-any.

Usually the only time you'd be dealing with such cases like these is if an external library type has given them to you.

Do you have a real-world example of this that a combination of all of the current no-unsafe rules plus no-explicit-any wouldn't handle?

Yes, @bradzacher, I agree that this error will usually pop up if you use a badly typed external library (though I'll be happy to catch those too). I didn't encounter a real-world example; this mostly started as a discussion at #10051 (comment).

Out of curiosity, I did write a rough implementation of this and ran it on typescript-eslint's codebase (not including checking function types, just checking unions recursively). I found one valid issue here. A similar issue did pop two more times: 1, 2. Here's a playground link with a smaller repro.

I'll add that on my (potentially faulty) implementation, the time it takes to lint typescript-eslint's entire project did increase from ~51 to ~64 seconds on my local machine.

I don't know if this is worth the extra complexity and time the rule will take to execute (time can probably be improved though).

@bradzacher
Copy link
Member

The extra time would be because all type information is computed lazily - the more you access, the more that gets computed.

So by going deeper into the inspections of things it doesn't surprise me that the rule gets slower!

@bradzacher bradzacher added evaluating community engagement we're looking for community engagement on this issue to show that this problem is widely important and removed triage Waiting for team members to take a look labels Nov 16, 2024
@JoshuaKGoldberg
Copy link
Member

Tempting, but I'm not in favor. I get the appeal of more deeply checking for anys, but if those nested properties actually get used, then I think they would get reported most of the time. The element.type.keys() examples are nice motivators but IME not super commonplace. This'd quite a lot of work + a bit of performance bloat for IMO not very much gain.

@ronami
Copy link
Member Author

ronami commented Jan 1, 2025

Tempting, but I'm not in favor. I get the appeal of more deeply checking for anys, but if those nested properties actually get used, then I think they would get reported most of the time. The element.type.keys() examples are nice motivators but IME not super commonplace. This'd quite a lot of work + a bit of performance bloat for IMO not very much gain.

I like having rules be as strict as they can be, but I agree that fringe examples aside, it's not worth the extra complexity and the performance hit.

The issue has been open for just over two and a half months with no community reactions.

I think it can be closed πŸ‘

@JoshuaKGoldberg JoshuaKGoldberg closed this as not planned Won't fix, can't repro, duplicate, stale Jan 1, 2025
@JoshuaKGoldberg JoshuaKGoldberg added wontfix This will not be worked on and removed evaluating community engagement we're looking for community engagement on this issue to show that this problem is widely important labels Jan 1, 2025
@github-actions github-actions bot added the locked due to age Please open a new issue if you'd like to say more. See https://typescript-eslint.io/contributing. label Jan 9, 2025
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 9, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working locked due to age Please open a new issue if you'd like to say more. See https://typescript-eslint.io/contributing. package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

3 participants