Skip to content

Instantly share code, notes, and snippets.

@Schniz
Created September 5, 2019 10:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Schniz/6bc10ceeadd194e5d019ae06ac528a26 to your computer and use it in GitHub Desktop.
Save Schniz/6bc10ceeadd194e5d019ae06ac528a26 to your computer and use it in GitHub Desktop.
////////////////////////////////////////////////////////////// Array utilities
type Length<T extends any[]> = T["length"];
type Head<T extends any[]> = T[0];
type Tail<T extends any[]> = ((...xs: T) => any) extends ((_x: any, ...xs: infer R) => any) ? R : [];
type AllTrue<Ts extends any[]> = {
0: true,
1: false,
2: AllTrue<Tail<Ts>>
}[Length<Ts> extends 0 ? 0 : Head<Ts> extends false ? 1 : 2]
////////////////////////////////////////////////////////////// Basic numbering
type _0 = "zero";
type Succ<T> = [T, '+1'];
type _1 = Succ<_0>;
type _2 = Succ<_1>;
type _3 = Succ<_2>;
type _4 = Succ<_3>;
type _5 = Succ<_4>;
////////////////////////////////////////////////////////////// Number functions
type MinOne<T> = T extends Succ<infer R> ? R : never;
type Min<T, Num> = {
0: T,
1: Min<MinOne<T>, MinOne<Num>>
}[Num extends _0 ? 0 : 1]
type Add<T, Num> = {
0: T,
1: Add<Succ<T>, MinOne<Num>>
}[Num extends _0 ? 0 : 1]
type IsLowerThan<T, Num> = {
0: false,
1: true,
2: IsLowerThan<MinOne<T>, Num>
}[T extends never ? 0 : T extends Num ? 0 : T extends _0 ? 1 : 2]
type IsMultOf<T, Num> = {
0: true,
1: false,
2: IsMultOf<Min<T, Num>, Num>
}[IsLowerThan<T, Num> extends true ? 1 : T extends Num ? 0 : T extends never ? 1 : 2];
////////////////////////////////////////////////////////////// Fizz buzz!
type IsFizz<T> = IsMultOf<T, _3>;
type IsBuzz<T> = IsMultOf<T, _5>;
type IsFizzBuzz<T> = AllTrue<[IsFizz<T>, IsBuzz<T>]>;
// the nth element
type FizzBuzzNth<Nth> = IsFizzBuzz<Nth> extends true ? "FizzBuzz" : IsFizz<Nth> extends true ? "Fizz" : IsBuzz<Nth> extends true ? "Buzz" : Nth;
////////////////////////////////////
type Unshift<E, Xs extends any[]> = Parameters<(e: E, ...xs: Xs) => any>;
type BuildFizzBuzzArray<Nth, Current extends any[] = []> = {
0: Current,
1: BuildFizzBuzzArray<MinOne<Nth>, Unshift<FizzBuzzNth<Nth>, Current>>
}[Nth extends _0 ? 0 : 1];
////////
type Mult<T, Num, Current = _0> = {
0: Current,
1: Mult<T, MinOne<Num>, Add<Current, T>>
}[Num extends _0 ? 0 : 1];
type _15 = Mult<_3, _5>;
///////////////
type __target__ = _15;
type __test__ = BuildFizzBuzzArray<__target__>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment