Reputation: 4085
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
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
1 except for never
Upvotes: 3
Reputation: 1801
another way to detect IsAny:
type IsAny<T> = (
unknown extends T
? [keyof T] extends [never] ? false : true
: false
);
Upvotes: 7
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