Typically, a typeguard's type is defined as such:
(value: unknown) => value is Type
Where the highlighted part is called a type predicate by the documentation:
(value: unknown) => **value is Type**
Going even forward, we could say (I don't know how, if even, the docs defines this) that the value
is the typeguard's parameter, is
is a TypeScript binary operator/keyword for defining type predicates and Type
is the type the typeguard actually guarantee, the guaranteed type.
Since we use typeguards to guarantee a value's type, we could say that Type
is the most interesting part of the definition.
Being such, is it possible to extract Type
from the type definition of a typeguard? How?
I'm thinking of something like:
type Type = typeof typeguard; // (value: unknown) => value is Type
type TypePredicate = TypePredicateOf<Type>; // value is Type
type GuaranteedType = IsOf<TypePredicate>; // Type
Where GuaranteedType
is the desired result.
Googling around, I've only found answers about generic typeguards type definitions, but did not get how to get the Type
part from it.
You can use conditional type inference with the infer
keyword to extract the guarded type from a type guard signature. Something like:
type GuardedType<T> = T extends (x: any) => x is infer U ? U : never;
And given some user-defined type guards:
function isString(x: any): x is string {
return typeof x === "string";
}
interface Foo {
a: string;
}
function isFoo(x: any): x is Foo {
return "a" in x && typeof x.a === "string"
}
You can see that it works as advertised:
type S = GuardedType<typeof isString>; // string
type F = GuardedType<typeof isFoo>; // Foo
Okay, hope that helps; good luck!