Simplify complicated Typescript - KISS

When it comes to Typescript, less can often be more. In an era of software development where complexity seems to be a rite of passage, I'm a strong proponent of the KISS (Keep It Stupid Simple) principle. It's all too easy to create intricate, overly complex structures in Typescript that not only complicate the coding process, but also make the code harder to review, test, and maintain.
In this post, we'll dive into some examples of how to simplify complicated Typescript and make your life as a developer a little less complicated.

Simplifying Functions in Typescript

Consider a function that simply doubles a given number:

function simpleDouble(num) {
  return { result: num * 2 }
}

This is a simple function. It takes a number as a parameter, doubles it, and returns an object with the result key and the doubled number as a value. However, this function could be refactored to include type definitions for clarity:

function simpleDoubleEx(num: number): { result: number} {
  return { result: num * 2 }
}

In the refactored function, we defined the parameter num type as a number and the return type as an object. This gives us clarity and consistency.

When Simple Becomes Complex

Despite the clarity and simplicity these examples provide, it's quite common to end up with functionality like this:

interface IStupidComplicated<A> {
  result: number | A;
}

function complicatedShit<T, A>(num: number | null) {
  return {
    result: (num! * 2 as A) ?? 0 as T
  } satisfies IStupidComplicated<T | A>;
}
console.log(complicatedShit(2)); // {result: 4}

At first glance, this level of complexity may seem necessary, but is it? Let's break it down. This function tries to account for every possible edge case and combination of inputs. However, as developers, we should question whether this complexity is really necessary. It adds multiple layers of complexity to the code, making it harder to read, understand, and maintain. This simple function serves the same purpose and provides the same output. As shown, the simpler alternative is just as effective without the unnecessary complexity; remember, in software development, simplicity often wins. Don't complicate your Typescript, or your life, more than necessary. Keep it stupidly simple.

Conclusion

The beauty of Typescript is its simplicity. It's perfectly fine to deal with complex logic in our applications, but it's imperative that we do so in a way that maintains readability and ease of understanding. Remember, the KISS principle is the key to writing successful, efficient, and clean Typescript code.