Hi
Use TypeScript, not JavaScript
Many developers already use TypeScript, but why? Why add complexity when good old JavaScript does the job, and does it well?
Aside from the obvious benefits like static typing, TypeScript provides a wealth of built-in type constructs, linting, and more.
Static Typing
Static types can provide great value. Even if you don't use custom types or interfaces, the value is still there, because we can pick up possible errors at compile time or earlier.
const numCars = 123;
const numCars = 123; // Type inference sets this to a 'number' type
In this example, the code is exactly the same, yet we get all the benefits of TypeScript (through type inference). If we want to call a function that accepts a string as a parameter, our IDE or compiler will not let us pass this number variable:
function formatDate(date: string) {}
formatDate(numCars); // ERROR - incorrect type
JavaScript would not be able to pick this error up, and would fail at runtime.
TypeScript can pick up this error because our IDE uses something called static analysis. This is where the IDE constantly analyses your code to try and find errors. If found, it will highlight the errors:
Unit testing and hasOwnProperty checks
Because of the nature of TypeScript, we require fewer unit tests than we would need with JavaScript. If we want to perform meaningful unit testing in JavaScript then we need to test the data types. TypeScript literally solves this problem out of the box.
const houseForSale = {
hasBath: true,
numberOfBedrooms: 4,
};
expect(houseForSale).toHaveProperty("hasBath");
expect(houseForSale).toHaveProperty("numberOfBedrooms", 4);
expect(houseForSale).not.toHaveProperty("pool");
interface IHouse {
hasBath: boolean;
numberOfBedrooms: number;
}
const houseForSale: IHouse = {
hasBath: true,
numberOfBedrooms: 4,
};
In the second example, we do not need to test if the properties are there / absent. The compiler does this for us!
Another time this is a blessing is in general application logic; imagine you have a function sellHouse:
function sellHouse(houseForSale) {
if (!houseForSale.hasOwnProperty("hasBath")) {
// !!! Runtime problem - what do we even do here?
return false;
}
// ...rest of function
}
function sellHouse(houseForSale: IHouse) {
// ...rest of function
}
As you can see, we need to validate objects and handle type errors in JavaScript at runtime, whereas TypeScript handles this inherently.
Don't be scared by complex types
Often, you will see TypeScript examples like this:
type ThisParameterType<T> = T extends (this: infer U, ...args: any[]) => any ? U : unknown;
In most webapps you will not have to deal with code like this. In most cases, you can safely ignore complex type features, and your code will look more like JavaScript.
I personally prefer functional programming techniques to write cleaner, decoupled code with less complexity.
Remember to keep it simple.
Disadvantages of TypeScript
Not too long ago, my team started a new Vue project. We voted for TypeScript because the benefits were obvious to us. We also opted for Vuex because we had all used it before and it is the 'standard' among Vue applications.
That is where things started to get annoying. Vuex doesn't support TypeScript as well as we had hoped. It resulted in lots of extra boilerplate and we had to fix more bugs because of it. We ended up switching to Pinia because it supported TypeScript extremely well out of the box.
This situation could have been avoided had we just used JavaScript. However, I still believe the benefits of TypeScript made it worth it.
TypeScript also inherently adds boilerplate (definition files, tsconfig) and requires more code in many cases. Although I favour less code in general, I believe the trade-off to be worth it.
As we have seen, TypeScript moves bugs from runtime to build time. It can help you ship software sooner and more frequently. In a few cases, it can reduce the amount of code you need to write.
Hopefully I have provided some food for thought to help influence your decision in your next project. Remember that you can use both TypeScript and JavaScript together, and gradually convert your JavaScript files over to TypeScript.