Sam Denty
Sam Denty

Reputation: 4085

Typescript check for the 'any' type

Is it possible to check for the exact any type using typescript conditionals?

type IsAny<T> = T extends any ? true : never

type A = IsAny<any> // true
type B = IsAny<number> // never
type C = IsAny<unknown> // never
type D = IsAny<never> // never

Upvotes: 37

Views: 6530

Answers (3)

Behemoth
Behemoth

Reputation: 9300

You can (ab)use the fact that any is both a subtype and a supertype of almost1 everything. So the inner (Distributive) Conditional Type resolves to a Union of true | false (=boolean) instead of either of them. I checked if T extends never but it works with pretty much any other type too.

type IsAny<T> = boolean extends (T extends never ? true : false) ? true : false;

type A = IsAny<any> // true
type B = IsAny<number> // false
type C = IsAny<unknown> // false
type D = IsAny<never> // false
type E = IsAny<void> // false
type F = IsAny<{}> // false
type G = IsAny<object> // false
type H = IsAny<undefined> // false
type I = IsAny<null> // false

TypeScript Playground


1 except for never

Upvotes: 3

eczn
eczn

Reputation: 1801

another way to detect IsAny:

type IsAny<T> = (
  unknown extends T
    ? [keyof T] extends [never] ? false : true
    : false
);

result of IsAny with some values

Upvotes: 7

jcalz
jcalz

Reputation: 327819

Yeah, you can test for any:

type IfAny<T, Y, N> = 0 extends (1 & T) ? Y : N; 
type IsAny<T> = IfAny<T, true, never>;
type A = IsAny<any> // true
type B = IsAny<number> // never
type C = IsAny<unknown> // never
type D = IsAny<never> // never

The explanation for this is in this answer. In short, any is intentionally unsound, and violates the normal rules of types. You can detect this violation because it lets you do something crazy like assign 0 to 1.

Upvotes: 51

Related Questions