-
-
Save miyaokamarina/934887ac2aff863b9c73283acfb71cf0 to your computer and use it in GitHub Desktop.
// Licensed under CC BY 4.0. | |
type $If<X: boolean, Then, Else = empty> = $Call< | |
& ((true, Then, Else) => Then) | |
& ((false, Then, Else) => Else), | |
X, | |
Then, | |
Else, | |
>; | |
type $Not<X: boolean> = $If<X, false, true>; | |
type $And<X: boolean, Y: boolean> = $If<X, Y, false>; | |
type $Or<X: boolean, Y: boolean> = $If<X, true, Y>; | |
type $Gte<X, Y> = $Call< | |
& ($Subtype<X> => true) | |
& (mixed => false), | |
Y, | |
>; | |
//// | |
declare var a: $Gte<number, string>; | |
/* error 1 */ (a: true); | |
/* ok */ (a: false); | |
declare var b: $Gte<number, number>; | |
/* ok */ (b: true); | |
/* error 2 */ (b: false); | |
declare var c: $If<true, 1, 2>; | |
/* ok */ (c: 1); | |
/* error 3 */ (c: 2); | |
declare var d: $If<false, 1, 2>; | |
/* error 4 */ (d: 1); | |
/* ok */ (d: 2); | |
//// | |
declare var e: $If<$Gte<number, string>, 1, 2>; | |
/* error 5 */ (e: 1); | |
/* ok */ (e: 2); | |
declare var f: $If<$Gte<number, number>, 1, 2>; | |
/* ok */ (f: 1); | |
/* error 6 */ (f: 2); | |
//// | |
type IsNumber<X> = $Gte<number, X>; | |
type NumberTo12<X> = $If<IsNumber<X>, 1, 2>; | |
declare var g: NumberTo12<string>; | |
/* error 7 */ (g: 1); | |
/* ok */ (g: 2); | |
declare var h: NumberTo12<number>; | |
/* ok */ (h: 1); | |
/* error 8 */ (h: 2); |
This is awesome. Thank you! However, flow docs state that $Subtype is now deprecated — https://flow.org/en/docs/types/utilities/#toc-subtype
$Supertype as well, although it is not used here.
Anyone know, what's the new way to do something like this?
type $Gte<X, Y> = $Call<
& ($Subtype<X> => true)
& (mixed => false),
Y,
>;
This is so good! Thank you! This no longer works on these lines (among others)
declare var a: $Gte<number, string>;
/* error 1 */ (a: true);
/* ok */ (a: false);
because a: true type checks and a: false does not. Was this an error in the original version of this gist? Or was this affected by the deprecation of $Subtype?
FWIW
declare var a2: $Gte<string, number>;
(a2: true);
(a2: false); // error
Fails in the same way. In other words, $Gte seems to always return true (as would be indicated by the $Subtype deprecation notice.)
if anyone is interested i have version of this without $Subtype
https://gist.github.com/thecotne/6e5969f4aaf8f253985ed36b30ac9fe0
$If
seems to break when Then
and Else
are not a similar type and $If
is instantiated with a boolean generic type parameter. Otherwise quite ingenious though I wish Flow would just have native support for conditional types like TypeScript does.
Thanks to you @miyaokamarina, typing overloading of my library finally works out, thank you thank you!!!
@zhirzh, it's on https://flow.org/en/docs/types/intersections/#toc-intersection-type-syntax .
A & B
and& A & B
are equivalent.