Alexander Bass


A friend of mine challenged me to program Tetris. I’ve wanted to make it for a while and it’s not too complicated, but I never got around to it. This challenge was just what I needed to finally make Tetris.

Screenshot of Froobtris

Click to play Froobtris

I have used TypeScript before, but have never fully immersed myself in it. Admittedly I still haven’t fully immersed myself, but this project has helped me appreciate it more. One of my gripes with TypeScript was that methods like document.getElementById("a") have a return type that is either an HTMLElement, or possibly null. The ambiguity can be circumvented by assuming that the return value will always be an HTMLElement with the as keyword, but sometimes it’s not. When the type is inevitably null, an error will likely happen downstream from the code and the type system will be none the wiser. The type-safe way to handle possibly null types is to write a bunch of type guards, but this gets cumbersome very quickly.

I ended up recreating something like Rust’s Option Type: a generic option type type Option<T> = T | null | undefined. The type is only an alias, so it compiles down to nothing, and better yet, it works with most of JavaScripts possibly null/undefined return types. In the example above, document.getElementById("a")’s return type is equivalent to Option<HTMLElement>. With the simple Option<T> type, I was able to, recreate much of Rust’s option functionality like: if let, unwrap, and expect. I might write a blog post about the option type I made in the future; I’ll link it here if I do.

The ‘Stack’

I don’t like diving deep into tooling and libraries if I can help it. In fact, this has been my first use of Webpack. Webpack certainly fits into the ’npm ecosystem’ a lot more than my previous strategy of cobbling shell scripts and makefiles so I think its use justified for this project.

Here are all the tools I used:

What’s with the name?

I just think the nonsensical word ‘froob’ is funny.

froob + Tetris = Froobtris

The source code is available at