Skip to content

Instantly share code, notes, and snippets.

@dfee
Created February 20, 2020 23:22
Show Gist options
  • Save dfee/df3b2cdd68761f154ac290c79968f30c to your computer and use it in GitHub Desktop.
Save dfee/df3b2cdd68761f154ac290c79968f30c to your computer and use it in GitHub Desktop.
Typing the technical interview with TypeScript (code sample)
type And<A, B> = A extends true ? B extends true ? true : false : false;
type Eq<A, _B extends A> = "passes";
type test_eq = [
Eq<"Hello", "Hello">,
Eq<"World", "World">,
]
type NAN = "invalid number";
type Increment<N> = [N, "+1"];
type Decrement<N> = N extends Increment<infer I> ? I : NAN;
type _0 = 0;
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 _16 = Increment<_15>;
type _17 = Increment<_16>;
type _18 = Increment<_17>;
type _19 = Increment<_18>;
type _20 = Increment<_19>;
type test_decrement = [
Eq<Decrement<_0>, NAN>,
Eq<Decrement<_1>, _0>,
Eq<Decrement<Decrement<_2>>, _0>,
]
type Subtract<N, Amount> = {
0: N;
1: Subtract<Decrement<N>, Decrement<Amount>>;
}[Amount extends _0 ? 0 : 1]
type test_sub = [
Eq<Subtract<_1, _1>, _0>,
Eq<Subtract<_2, _1>, _1>,
Eq<Subtract<_3, _1>, _2>,
Eq<Subtract<_1, _3>, NAN>,
];
type IsDivisableBy<A, B> = {
0: false,
1: true,
2: IsDivisableBy<Subtract<A, B>, B>;
}[B extends NAN ? 0 : A extends NAN ? 0 : A extends _0 ? 1 : 2]
type test_divisable_by = [
Eq<IsDivisableBy<_4, _2>, true>,
Eq<IsDivisableBy<_3, _2>, false>,
Eq<IsDivisableBy<_5, _3>, false>,
Eq<IsDivisableBy<_6, _3>, true>
];
type IsDivisableBy3<N> = IsDivisableBy<N, _3>;
type IsDivisableBy5<N> = IsDivisableBy<N, _5>;
type IsDivisableBy15<N> = And<IsDivisableBy3<N>, IsDivisableBy5<N>>;
type FizzBuzzNth<N> = IsDivisableBy15<N> extends true
? "FizzBuzz"
: IsDivisableBy3<N> extends true
? "Fizz"
: IsDivisableBy5<N> extends true
? "Buzz"
: N;
type test_fizzbuzznth = [
Eq<FizzBuzzNth<_1>, _1>,
Eq<FizzBuzzNth<_2>, _2>,
Eq<FizzBuzzNth<_3>, "Fizz">,
Eq<FizzBuzzNth<_4>, _4>,
Eq<FizzBuzzNth<_5>, "Buzz">,
Eq<FizzBuzzNth<_6>, "Fizz">,
Eq<FizzBuzzNth<_14>, _14>,
Eq<FizzBuzzNth<_15>, "FizzBuzz">,
Eq<FizzBuzzNth<_16>, _16>
];
type Unshift<Element, List extends Array<any>> = Parameters<
(e: Element, ...list: List) => any
>;
type test_unshift = [
Eq<Unshift<1, []>, [1]>,
Eq<Unshift<2, [1]>, [2, 1]>,
Eq<Unshift<"hello", [2, 1]>, ["hello", 2, 1]>
];
type FizzBuzzUpTo<N, Output extends any[] = []> = {
0: Output;
1: FizzBuzzUpTo<Decrement<N>, Unshift<FizzBuzzNth<N>, Output>>;
}[N extends _0 ? 0 : 1];
type test_fizzbuzzupto = [
Eq<
FizzBuzzUpTo<_20>,
[
_1, _2, "Fizz", _4, "Buzz",
"Fizz", _7, _8, "Fizz", "Buzz",
_11, "Fizz", _13, _14, "FizzBuzz",
_16, _17, "Fizz", _19, "Buzz"
]
>
];
// Using "normal" numbers :D
// type Increment<N> = [
// 1, 2, 3, 4, 5,
// 6, 7, 8, 9, 10,
// 11, 12, 13, 14, 15,
// 16, 17, 18, 19, 20
// ][Extract<N, number>];
// type Decrement<N> = [
// NAN,
// 0, 1, 2, 3, 4, 5,
// 6, 7, 8, 9, 10,
// 11, 12, 13, 14, 15,
// 16, 17, 18, 19, 20
// ][Extract<N, number>];
// type test_fizzbuzzupto2 = [
// Eq<
// FizzBuzzUpTo<_20>,
// [
// 1, 2, "Fizz", 4, "Buzz",
// "Fizz", 7, 8, "Fizz", "Buzz",
// 11, "Fizz", 13, 14, "FizzBuzz",
// 16, 17, "Fizz", 19, "Buzz"
// ]
// >
// ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment