Detect the any type, and only any. Every obvious check produces false positives; the working one-liner is 0 extends 1 & T, and the why behind it is the real lesson.
The whole solution is one line, and almost every obvious attempt at it is wrong.
Sometimes it's useful to detect if you have a value with any type. This is especially helpful while working with third-party TypeScript modules, which can export any values in the module API. It's also good to know about any when you're suppressing implicitAny checks. The task: write a utility type IsAny<T> which takes input type T. If T is any, return true, otherwise return false.
type A = IsAny<any> // true
type B = IsAny<unknown> // false
type C = IsAny<never> // false
type D = IsAny<string> // falseThe challenge is deceptively short: any is deliberately assignable to and from everything, so every straightforward check produces false positives. The solution hinges on a property that any, and only any, has.
Sometimes it's useful to detect if you have a value with any type. This is especially helpful while working with third-party Typescript modules, which can export any values in the module API. It's also good to know about any when you're suppressing implicitAny checks.
So, let's write a utility type IsAny<T>, which takes input type T. If T is any, return true, otherwise, return false.
View on GitHub: https://tsch.js.org/223
Change the following code to make the test cases pass (no type check errors).
π Lifetime-License is leaving on August 10, 2026
Get it now for $29
One-time payment. Lifetime access to all pro challenges.
The solution, in full:
[object Object]One line, but it only makes sense once you see why the straightforward attempts fail.
Your first instinct is probably T extends any ? true : false. But everything extends any, that's its job, so this returns true for every type. Flipping it to any extends T ? true : false fails differently: when the type being checked (the left side of extends) is any, TypeScript resolves the conditional to the union of both branches. So for T = string you get true | false, which is just boolean. Only when the check is trivially true (say T is unknown or any itself) does it collapse to plain true, so this variant can't distinguish any from unknown either.
The tests raise the bar further: IsAny<unknown> and IsAny<never> must both be false. Those two are the usual casualties of sloppy any detection, because unknown also accepts everything and never also extends everything. You need a property that is unique to any alone.
any hasIntersecting with any swallows everything. For any normal type, an intersection can only narrow:
type A = 1 & string // never: a value can't be both 1 and a string
type B = 1 & number // 1: the narrower side wins
type C = 1 & unknown // 1: unknown is the identity for intersections
type D = 1 & any // any!That last line is the anomaly. any doesn't participate in intersection narrowing like other types; it absorbs the whole expression. 1 & any is any, full stop. No other type behaves this way: even 1 & unknown evaluates to 1.
Now read the solution as a probe:
[object Object]T is not any: 1 & T is either 1 (when T includes the literal 1) or never (when it doesn't). Is 0 assignable to 1? No. To never? Also no, nothing is assignable to never except never itself. The condition is false for every ordinary T.T is any: 1 & any collapses to any, and 0 extends any is trivially true.The literals 0 and 1 aren't magic; any two provably incompatible types work ('a' extends 'b' & T would do the same). What matters is that the left side can never satisfy the right side unless any has absorbed the intersection.
IsAny<unknown> β false: 1 & unknown is 1, and 0 extends 1 fails. unknown accepts everything as an assignment target, but it doesn't swallow intersections.IsAny<never> β false: 1 & never is never, and 0 extends never fails. Note that T sits on the right side of extends here, so the conditional never distributes over never (distribution only happens for a naked type parameter on the left). That placement keeps never from short-circuiting the whole conditional to never.IsAny<undefined> and IsAny<string> β false: both intersect with 1 to never, same story.IsAny is a foundational building block: once you can detect any reliably, you can write stricter utilities that refuse to let any sneak through generic code silently. The 0 extends 1 & T idiom appears verbatim in many production type libraries.
This challenge is originally from here.