Skip to content

Instantly share code, notes, and snippets.

@na-o-ys
Last active July 24, 2018 10:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save na-o-ys/34e9ebf7fc5a8097e3284a646a5ed436 to your computer and use it in GitHub Desktop.
Save na-o-ys/34e9ebf7fc5a8097e3284a646a5ed436 to your computer and use it in GitHub Desktop.
A type level FizzBuzz in TypeScript.
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