typescript

Get warned when using neither-explicit-nor-implicit any


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.


Solution

  • 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:

    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.