Can the Generic Types replace the type any?
I know that it is hardly recommended to avoid the use of type any
since it removes all type checking provided by typescript. In other words, it is not safe.
What is the better approach, to use unknown or generic types instead of any?
Example of function signature I want to adjust:
getTranslationByKeys(keys: any): any {}
The type of the keys and the return value are specified on the function's call (array, object...)
When it comes to function definitions, I think the blanket prohibition on using
any
, -- often stated as: "don't ever use it unless it's temporarily to help with a migration of javascript to typescript" -- is oversimplified. Specifically, I don't think the prohibition againstany
is nearly as strong when it is used as the constraint on a generic type parameter to a function. Indeed, I thinkany
can be quite a useful type when used in that context.I don't disagree that
any
is quite bad in the example you give.This is just completely opting out of the type system. For example, look at this call site:
I have no idea whether this function can execute on the parameters I've passed it or what
myResult
will be when its done (if it even can complete):Bad; for sure. But consider the following function typing:
It's got the word
any
in it. And certainly there are many lint rules that will yell at you for using this, and many texts on learning TypeScript that would lead you to believe this is a bad idea unless you are doing it temporarily for purposes of an upgrade.But I don't think that's really right in this case. Why isn't that a problem? Because unlike when you use
any
as a raw type, in this case you are not completely opting out of the type system. You will, in fact, still have strong type safety at the call site. For example, a call like:will be definitely typed.
myResult
will have typenumber[]
, and (at least I would argue), the lack of a constraint onkeys
is an explicit signal to the consumer that it is ok to pass in any type for the parameter.Now, you have given up some type-safety inside the function definition, in the sense that inside the function definition
keys
could literally be anything. But sometimes that's what you want. You may have a function that can, in fact, handle any type of input, like this (admittedly silly) function:While that particular code might be silly, my point is that I don't see anything about the typing of that code that is problematic. The typing will be strong at the call site and the code is accurately typed in the function definition. Even though the dreaded
any
is used!Someone could point out that what I've written above is really the same as just writing
getTranslationByKeys<T>
which you see all the time and, technically, doesn't have the wordany
in it. Fine, but that doesn't change anything above. The two statements are equivalent and one shouldn't be better just because the wordany
is hidden.Moreover,
any
can be used in much more useful ways in generic constraints. Consider the following example:This too contains the dreaded word
any
but it is a highly useful type of constraint. It says thatT
can be any object so long as it is, in fact, an object with string indices. That's hardly unconstrained and is actually far more precise than if you had saidT extends object
. I see and use this use ofany
all the time in function definitions.Now, could you use
unknown
here instead ofany
? Maybe. I confess I haven't usedunknown
enough with generic constraints to know how equivalent its behavior is. But, to me at least,unknown
seems less descriptive of what you are trying to convey in the situation above. At least from the perspective of the consumer of your function, you aren't intending to tell them "you can give me a string-indexed object with unknown type values", you actually mean "you can give me a string-indexed object with any values"--which is exactly what the wordany
conveys!So, my own opinion is that
any
, when used in the context of constraints on generic type parameters, can be quite useful and descriptive, and it should not be subject to the type of blanket prohibition one often hears for usingany
as a simple type.I'd be very interested to hear what others think on this topic.