typescript - Get warned when using neither-explicit-nor-implicit any - Stack Overflow

Can I be notified when I use a third-party function that returns (some variant of) any? (via a compiler

Can I be notified when I use a third-party function that returns (some variant of) any? (via a compiler error/warning, linter message, anything really...)

Motivating case: despite using tsc --noImplicitAny and eslint with @typescript-eslint/no-explicit-any, I did not know I was using a variable with type any.

I have some external data that boils down to:

interface T1 {
  name: string
  color: string
}

interface T2 {
  id: string
}

interface T3 {
  name: string
  height: number
}

interface Data {
  k1: {[key: string]: T1}
  k2: {[key: string]: T2}
  k3: {[key: string]: T3}
}

And, because T1 and T3 have something in common, I want to do the same operation on both:

function f(data: Data) {
  for (const key of ['k1', 'k3'] as const) {
    for (const v of Object.values(data[key])) {
      console.log(v.name)
    }
  }
}

Object.values has two overloads. My code evolved from using the type-safe one (Object.values<T>(o: {[s: string]: T}): T[]) to the version above, using the unsafe one (Object.values(o: {}): any[]) without me noticing, so I did not realize that v had type any until it was too late...

Of course there are tons of ways to refactor this code to make it type-safe. My question really is how to detect that it's not type-safe in the first place. Also my question is not about only Object.values but about any function that can return a variant of any.

I believe my question differs from How to prevent "any" from being used in TypeScript types and interfaces because I don't have the word "any" anywhere in my code, so the situation I'm describing is even more tricky.

Can I be notified when I use a third-party function that returns (some variant of) any? (via a compiler error/warning, linter message, anything really...)

Motivating case: despite using tsc --noImplicitAny and eslint with @typescript-eslint/no-explicit-any, I did not know I was using a variable with type any.

I have some external data that boils down to:

interface T1 {
  name: string
  color: string
}

interface T2 {
  id: string
}

interface T3 {
  name: string
  height: number
}

interface Data {
  k1: {[key: string]: T1}
  k2: {[key: string]: T2}
  k3: {[key: string]: T3}
}

And, because T1 and T3 have something in common, I want to do the same operation on both:

function f(data: Data) {
  for (const key of ['k1', 'k3'] as const) {
    for (const v of Object.values(data[key])) {
      console.log(v.name)
    }
  }
}

Object.values has two overloads. My code evolved from using the type-safe one (Object.values<T>(o: {[s: string]: T}): T[]) to the version above, using the unsafe one (Object.values(o: {}): any[]) without me noticing, so I did not realize that v had type any until it was too late...

Of course there are tons of ways to refactor this code to make it type-safe. My question really is how to detect that it's not type-safe in the first place. Also my question is not about only Object.values but about any function that can return a variant of any.

I believe my question differs from How to prevent "any" from being used in TypeScript types and interfaces because I don't have the word "any" anywhere in my code, so the situation I'm describing is even more tricky.

Share Improve this question edited Feb 24 at 6:10 jacquev6 asked Feb 23 at 13:26 jacquev6jacquev6 6464 silver badges19 bronze badges 3
  • This question is similar to: How to prevent "any" from being used in TypeScript types and interfaces. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. – Alexander Nenashev Commented Feb 23 at 14:09
  • 1 Maybe you're looking for the ts-eslint no-unsafe-argument, no-unsafe-call, no-unsafe-assignment, no-unsafe-member-access, and no-unsafe-return rules? I don't see a single "prohibit all any everywhere" rule but the combination of those with no-explicit-any and TS's --noImplicitAny should cover most things. Does that fully address the question? If so I'll write an answer; if not, what's missing? – jcalz Commented Feb 23 at 16:47
  • @jcalz You suggestion does indeed catch the situation I'm describing. I will accept your answer. – jacquev6 Commented Feb 24 at 6:12
Add a comment  | 

1 Answer 1

Reset to default 1

As far as I can tell there is no single compiler setting or linter rule that completely banishes the any type. But it does look there is a set of settings and rules that, together, have this effect (or close to it). See Avoiding anys with Linting and TypeScript for more information. You might want to enable all of these:

  • TypeScript's --noImplicitAny compiler setting will warn you if any appears as the result of a failure/fallback in the TypeScript language itself.

  • @typescript-eslint/no-explicit-any will warn you if any explicitly appears inside your code as an annotated type.

  • @typescript-eslint/no-unsafe-argument will warn you if you call a function with an argument of type any.

  • @typescript-eslint/no-unsafe-assignment will warn you if you assign a value of type any to a variable or property.

  • @typescript-eslint/no-unsafe-call will warn you if you call a value of type any like a function.

  • @typescript-eslint/no-unsafe-member-access will warn you if you index into a value of type any.

  • @typescript-eslint/no-unsafe-return will warn you if you call a function that returns any.

There are other linter rules that avoid various unsafe things, but these should cover most cases.

Of course if you do enable these you can expect lots of warnings all over the place, because whether we like it or not, any appears quite often in TypeScript's libraries. The longstanding feature request at microsoft/TypeScript#26188 to replace such anys with safe versions like unknown or never (depending on variance, see Difference between Variance, Covariance, Contravariance, Bivariance and Invariance in TypeScript) has not been implemented because it really breaks a lot of things and is harder for developers to reason about (see microsoft/TypeScript#24737). For those serious about excising any entirely, or only manually allowing it in specific places in the code, this might still be a reasonable course of action. For everyone else, it might not be worth the hassle.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745153523a4613976.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信