typescript - Hämta typ från typeguards typ-predikat
Vanligtvis definieras en typvaktens typ på följande sätt:
(value: unknown) => value is Type
Där den markerade delen kallas en type predicate enligt dokumentationen:
(value: unknown) => **value is Type**
Att gå ännu längre, skulle vi kunna säga (jag vet inte hur, om ens, dokumentationen definierar detta) att value är typeguardens parameter, is är en TypeScript binär operator/nyckelord för att definiera typepredikat och Type är den typ som typeguarden faktiskt garanterar, den garanterade typen. Eftersom vi använder typeguards för att garantera en värdes typ, skulle vi kunna säga att Type är den mest intressanta delen av definitionen.
Att vara sådan, är det möjligt att extrahera Type från typdefinitionen av en typvakt? Hur?
Jag tänker på något som:
type Type = typeof typeguard; // (value: unknown) => value is Type
type TypePredicate = TypePredicateOf<Type>; // value is Type
type GuaranteedType = IsOf<TypePredicate>; // Type
Där GuaranteedType är det önskade resultatet.
När jag googlat runt har jag bara hittat svar om generiska typvaktsdefinitioner, men jag har inte förstått hur man får Type-delen från det.
Svar #1
Du kan använda villkorlig typinferens med infer-nyckelordet för att extrahera den skyddade typen från en typvaktssignatur. Något som:
type GuardedType<T> = T extends (x: any) => x is infer U ? U : never;
Och med vissa användardefinierade typvakter:
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"
}
Du kan se att det fungerar som utlovat:
type S = GuardedType<typeof isString>; // string
type F = GuardedType<typeof isFoo>; // Foo
Okej, hoppas det hjälper; lycka till!
Playground-länk till kod
