Last active
July 24, 2018 10:18
-
-
Save na-o-ys/34e9ebf7fc5a8097e3284a646a5ed436 to your computer and use it in GitHub Desktop.
A type level FizzBuzz in TypeScript.
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 Zero = 0 | |
type Num = Zero | { 0: Num } | |
const any: any = null | |
function succ<T>(v: T): { 0: T } { | |
return any | |
} | |
type FizzNum = Zero | {0:{0:{0: FizzNum }}} | |
type BuzzNum = Zero | {0:{0:{0:{0:{0: BuzzNum }}}}} | |
type FizzBuzzNum = Zero | {0:{0:{0:{0:{0:{0:{0:{0:{0:{0:{0:{0:{0:{0:{0: FizzBuzzNum }}}}}}}}}}}}}}} | |
type Fizz = { fizz } | |
type Buzz = { buzz } | |
type FizzBuzz = { fizzBuzz } | |
function evalFizzBuzz(n: FizzBuzzNum): FizzBuzz | |
function evalFizzBuzz(n: FizzNum): Fizz | |
function evalFizzBuzz(n: BuzzNum): Buzz | |
function evalFizzBuzz<Num>(n: Num): Num | |
function evalFizzBuzz(n) { return any } | |
const n1 = succ(any as Zero) | |
const n2 = succ(n1) | |
const n3 = succ(n2) | |
const n4 = succ(n3) | |
const n5 = succ(n4) | |
const n6 = succ(n5) | |
const n7 = succ(n6) | |
const n8 = succ(n7) | |
const n9 = succ(n8) | |
const n10 = succ(n9) | |
const n11 = succ(n10) | |
const n12 = succ(n11) | |
const n13 = succ(n12) | |
const n14 = succ(n13) | |
const n15 = succ(n14) | |
function assertType<T>(v: T, t: T) {} | |
// Successful Typing | |
assertType(evalFizzBuzz(n1), n1) | |
assertType(evalFizzBuzz(n2), n2) | |
assertType(evalFizzBuzz(n3), any as Fizz) | |
assertType(evalFizzBuzz(n4), n4) | |
assertType(evalFizzBuzz(n5), any as Buzz) | |
assertType(evalFizzBuzz(n6), any as Fizz) | |
assertType(evalFizzBuzz(n7), n7) | |
assertType(evalFizzBuzz(n8), n8) | |
assertType(evalFizzBuzz(n9), any as Fizz) | |
assertType(evalFizzBuzz(n10), any as Buzz) | |
assertType(evalFizzBuzz(n11), n11) | |
assertType(evalFizzBuzz(n12), any as Fizz) | |
assertType(evalFizzBuzz(n13), n13) | |
assertType(evalFizzBuzz(n14), n14) | |
assertType(evalFizzBuzz(n15), any as FizzBuzz) | |
// Failure Typing | |
assertType(evalFizzBuzz(n1), n2) | |
assertType(evalFizzBuzz(n1), any as Fizz) | |
assertType(evalFizzBuzz(n3), n3) | |
assertType(evalFizzBuzz(n5), any as FizzBuzz) | |
assertType(evalFizzBuzz(n15), any as Fizz) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment