Created
May 4, 2021 03:45
-
-
Save dyerw/81b52003beb7e32c9c9a4e9f39741068 to your computer and use it in GitHub Desktop.
TS Type-level Fizzbuzz
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Count<A, S extends 0[] = []> = A extends S["length"] | |
? S | |
: Count<A, [...S, 0]>; | |
type IncC<A> = [...Count<A>, 0]; | |
type DecC<A> = Count<A> extends [infer _H, ...(infer R)] ? R : []; | |
// Basic Arithmetic | |
type Inc<A> = IncC<A>["length"]; | |
type Dec<A> = DecC<A>["length"]; | |
type Add<A, B> = B extends 0 ? A : Add<Inc<A>, Dec<B>>; | |
type Sub<A, B> = B extends 0 ? A : Sub<Dec<A>, Dec<B>>; | |
type Mul<A, B, R = 0> = B extends 0 ? R : Mul<A, Dec<B>, Add<R, A>>; | |
type Div_<A, B, R = 0> = A extends 0 ? R : Div_<Sub<A, B>, B, Inc<R>>; | |
type Div<A, B> = Mul<B, Div_<A, B>> extends A | |
? Div_<A, B> | |
: Dec<Div_<A, B>>; | |
type Mod<A, B> = Sub<A, Mul<B, Div<A, B>>>; | |
// Logical operators | |
type Equal<A, B> = A extends B ? B extends A ? true : false : false; | |
type And<A, B> = A extends true ? B extends true ? true : false : false; | |
type Or<A, B> = A extends true | |
? true | |
: (B extends true ? true : false); | |
// Fizzbuzzin' | |
type Mod5<A> = Equal<0, Mod<A, 5>> extends true ? true : false; | |
type Mod3<A> = Equal<0, Mod<A, 3>> extends true ? true : false; | |
type Mod15<A> = And<Mod5<A>, Mod3<A>> extends true ? true : false; | |
type NumberToFizzBuzz<N> = Mod15<N> extends true | |
? "fizzbuzz" | |
: (Mod5<N> extends true | |
? "buzz" | |
: (Mod3<N> extends true | |
? "fizz" | |
: N)); | |
type FizzBuzzTo<N, R extends any[] = []> = N extends 0 | |
? R | |
: FizzBuzzTo<Dec<N>, [NumberToFizzBuzz<N>, ...R]> | |
type FizzBuzz = FizzBuzzTo<29>; // breaks after 29, foiled by the type instantiation limit |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment