Skip to content

Instantly share code, notes, and snippets.

@mkulke
Created December 30, 2020 23:25
Show Gist options
  • Save mkulke/420b5b09d3eaf8b77aca1cec6d7eba51 to your computer and use it in GitHub Desktop.
Save mkulke/420b5b09d3eaf8b77aca1cec6d7eba51 to your computer and use it in GitHub Desktop.
fizzbuzz in typescripts type system
// typescript v4.1.3
type _0 = 0;
type Increment<N> = [N, 1];
type Eq<A, B extends A> = true;
type _1 = Increment<_0>;
type _2 = Increment<_1>;
type _3 = Increment<_2>;
type _4 = Increment<_3>;
type _5 = Increment<_4>;
type _6 = Increment<_5>;
type _7 = Increment<_6>;
type _8 = Increment<_7>;
type _9 = Increment<_8>;
type _10 = Increment<_9>;
type _11 = Increment<_10>;
type _12 = Increment<_11>;
type _13 = Increment<_12>;
type _14 = Increment<_13>;
type _15 = Increment<_14>;
type Negative = -1
type Decrement<N>
= N extends Increment<infer M> ? M
: Negative;
type Subtract<N, S>
= S extends _0 ? N
: Subtract<Decrement<N>, Decrement<S>>;
type IsDivisibleBy<N, D>
= N extends Negative ? false
: N extends _0 ? true
: IsDivisibleBy<Subtract<N, D>, D>;
type And<A, B>
= A extends false ? false
: B extends false ? false
: true;
type IsDivisibleBy3<N> = IsDivisibleBy<N, _3>;
type IsDivisibleBy5<N> = IsDivisibleBy<N, _5>;
type IsDivisibleBy15<N> = And<IsDivisibleBy3<N>, IsDivisibleBy5<N>>;
type FizzBuzzNth<N>
= IsDivisibleBy15<N> extends true
? "FizzBuzz"
: IsDivisibleBy3<N> extends true
? "Fizz"
: IsDivisibleBy5<N> extends true
? "Buzz"
: N;
type Unshift<A, B extends any[]> = [A, ...B];
type FizzBuzzUpTo<N, O extends any[] = []>
= N extends _0
? O
: FizzBuzzUpTo<Decrement<N>, Unshift<FizzBuzzNth<N>, O>>;
type test = [
Eq<
FizzBuzzUpTo<_15>,
[
_1, _2, "Fizz", _4, "Buzz", "Fizz", _7, _8, "Fizz", "Buzz", _11, "Fizz", _13, _14, "FizzBuzz"
]
>
];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment