Skip to content

Instantly share code, notes, and snippets.

@evinism
Created April 29, 2022 05:46
Show Gist options
  • Save evinism/c1d1a9da6c8e07d6705b00d7b92049b4 to your computer and use it in GitHub Desktop.
Save evinism/c1d1a9da6c8e07d6705b00d7b92049b4 to your computer and use it in GitHub Desktop.
Type-level FizzBuzz in Typescript
/* Summon the naturals */
type Zero = 0;
type Succ<T extends Succ<any> | Zero> = {
next: T;
}
// Construct a few naturals.
type n0 = Zero;
type n1 = Succ<n0>;
type n2 = Succ<n1>;
type n3 = Succ<n2>;
type n4 = Succ<n3>;
type n5 = Succ<n4>;
// and so on...
// Continued in appendix.
// And some basic subtracty operations
type Pred<T> = T extends Succ<infer N> ? N : never;
type MathError = {error: "math error!"};
type Subtract<A, B> =
B extends n0
? A
: (
A extends n0
? MathError
: Subtract<Pred<A>, Pred<B>>
);
type EvenlyDividedBy<A, B> =
A extends MathError
? false
: (
A extends n0
? true
: EvenlyDividedBy<Subtract<A, B>, B>
)
// And given our utils, finish the job
type FizzBuzz<N> =
EvenlyDividedBy<N, n15> extends true
? "fizzbuzz"
: (
EvenlyDividedBy<N, n3> extends true
? "fizz"
: (
EvenlyDividedBy<N, n5> extends true
? "buzz"
: N
)
);
// Our job is complete
type f45 = FizzBuzz<n45>;
type f46 = FizzBuzz<n46>;
type f47 = FizzBuzz<n47>;
type f48 = FizzBuzz<n48>;
// Appendix: A Bunch of Numbers
type n6 = Succ<n5>;
type n7 = Succ<n6>;
type n8 = Succ<n7>;
type n9 = Succ<n8>;
type n10 = Succ<n9>;
type n11 = Succ<n10>;
type n12 = Succ<n11>;
type n13 = Succ<n12>;
type n14 = Succ<n13>;
type n15 = Succ<n14>;
type n16 = Succ<n15>;
type n17 = Succ<n16>;
type n18 = Succ<n17>;
type n19 = Succ<n18>;
type n20 = Succ<n19>;
type n21 = Succ<n20>;
type n22 = Succ<n21>;
type n23 = Succ<n22>;
type n24 = Succ<n23>;
type n25 = Succ<n24>;
type n26 = Succ<n25>;
type n27 = Succ<n26>;
type n28 = Succ<n27>;
type n29 = Succ<n28>;
type n30 = Succ<n29>;
type n31 = Succ<n30>;
type n32 = Succ<n31>;
type n33 = Succ<n32>;
type n34 = Succ<n33>;
type n35 = Succ<n34>;
type n36 = Succ<n35>;
type n37 = Succ<n36>;
type n38 = Succ<n37>;
type n39 = Succ<n38>;
type n40 = Succ<n39>;
type n41 = Succ<n40>;
type n42 = Succ<n41>;
type n43 = Succ<n42>;
type n44 = Succ<n43>;
type n45 = Succ<n44>;
type n46 = Succ<n45>;
type n47 = Succ<n46>;
type n48 = Succ<n47>;
type n49 = Succ<n48>;
type n50 = Succ<n49>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment