From e90b3968a33bbe0bc239e94d4ed0112c90f27d33 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Fri, 9 May 2025 14:28:07 -0400 Subject: [PATCH] docs(eslint-plugin): [no-explicit-any] add alternatives --- .../docs/rules/no-explicit-any.mdx | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/packages/eslint-plugin/docs/rules/no-explicit-any.mdx b/packages/eslint-plugin/docs/rules/no-explicit-any.mdx index f0c8c20c6dec..d38997b60a54 100644 --- a/packages/eslint-plugin/docs/rules/no-explicit-any.mdx +++ b/packages/eslint-plugin/docs/rules/no-explicit-any.mdx @@ -145,6 +145,36 @@ interface Garply { } ``` +## Alternatives to `any` + +Which type(s) to use instead of `any` depends on the context. + +### Type Parameter Constraints + +"Generic" type parameters are often used to represent a value of an unknown type. +It can be tempting to use `any` as a type parameter constraint, but this is not recommended. + +First, `extends any` on its own does nothing: `` is equivalent to ``. +See [`@typescript-eslint/no-unnecessary-type-constraint`](./no-unnecessary-type-constraint.mdx) for more information. + +Within type parameters, `never` and `unknown` otherwise can generally be used instead. +For example, the following code uses those two types in `AnyFunction` instead of `any`s to constrain `Callback` to any function type: + +```ts +type AnyFunction = (...args: never[]) => unknown; + +function curry(greeter: Greeter, prefix: string) { + return (...args: Parameters) => `${prefix}: ${greeter(...args)}`; +} + +const greet = (name: string) => `Hello, ${name}!`; +const greetWithDate = curry(greet, 'Logged: '); + +greetWithDate('linter'); // => "Logged: Hello, linter!" +``` + +See [When to use `never` and `unknown` in TypeScript](https://blog.logrocket.com/when-to-use-never-unknown-typescript) for more information on those types. + ## When Not To Use It `any` is always a dangerous escape hatch.