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
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
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
.
type IfAny<T, Y, N> = T extends never ? Y : N;
also seems to have same effect. It looks like T extends never
is distributed over T
even when T
is never
, not sure if it's intended or not. –
Stickney never
is considered the "empty union" so it always maps to never
in a distributive conditional type. It is interesting that any
doesn't get distributed, which is why that version of IfAny
can distinguish any
from never
... of course it does so by returning never
instead of N
, which is probably not desired. –
Petry @types/react
emits false (not never) when T is never: type IsExactlyAny<T> = boolean extends (T extends never ? true : false) ? true : false;
–
Orbit another way to detect IsAny:
type IsAny<T> = (
unknown extends T
? [keyof T] extends [never] ? false : true
: false
);
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
© 2022 - 2024 — McMap. All rights reserved.