Even though I've been working with JS in all ends for the past 4 years, it was only last year that I had the chance (and will) to use TypeScript.

It's nice to work with TS as it makes debugging, inspecting and making sense of the codebase easier. However, it may give us a false sense of safety by making us forget that the type system only works until transpilation.

Consider the following example:

type Response = {
  category: {
    description: string
  }
};

// [ ... ]

const request = await fetch(...);
const response = (await request.json()) as Response;

// [ ... ]

// category is undefined
return response.category.description

In this example, we are assuming our request will return a type Response, which contains a mandatory property category with description. As this property is mandatory, accessing response.category.description should be safe, as category should never be undefined. However, we can't guarantee this will be always true as it's coming from an external source.

Other typed languages, like Rust and Java, force us to handle those scenarios upfront, either by defining exception paths, default values or by explicitly assuming the risk of parsing issues. TypeScript chooses to trust the developer instead. Because of that, if we don't add proper input validation a bad input could go down many levels before it "explodes", making spotting issues very hard.

I've seen at least two issues caused by bad input validation since I started working with TS. Since then, I've been treating TypeScript types as a hint for developers during development, and not as a full-blown type system.

All things considered, working with TypeScript has been very satisfying, and I recommend giving it a chance. :)