Typesafe Function Overloading in TypeScript
Common frustrations with no easy solution
In the course of helping other developers new to TypeScript, there are various common patterns of frustration that I encounter. Two broad categories of problems:
- Type 1: Users get frustrated that certain patterns that are common in some JavaScript codebases are difficult to express in a typesafe way in TypeScript. Typically this involves some form of runtime reflection, which I'm not going to talk about today and is typically a problem for less experienced or especially stubborn users (sometimes legitimate stubbornness!).
- Type 2: Users understanding TypeScript features in isolation and get confused when they try to combine them in ways that seem conceptually natural, but do not work as expected. This is often simply because this combination of features has not been implemented yet and may never be implemented.
So we are going to talk about a type 2 problem, specifically function overloading and conditional types in TypeScript, which is an area of the language that I think lots of people find unsatisfactory and I've seen recreated countless times. The intersection between these two features appears to be a common theme from helping people on the officially unofficial TypeScript community discord server and at work. The motivation is type safety, but the result is confusing compiler errors.