img
Go back

Read

Published on: Jan 31, 2025

Programming

Typescript: Where to start?

If you’re a JavaScript developer looking to build more robust, scalable, and maintainable applications, TypeScript is your next best step. It’s a superset of JavaScript that adds static typing, bringing many benefits traditionally found in strongly typed languages like C# or Java.

Why Use a Typed Language Over a Dynamic One?

JavaScript is famously flexible, like Python, Ruby, or PHP; perhaps too flexible. While that makes it great for rapid prototyping, it introduces risks in larger codebases. These risks include runtime errors that could have been caught earlier, difficulties in maintaining and refactoring code, and challenges in ensuring consistent behavior across a team. TypeScript addresses these issues by adding static typing, which helps developers catch errors during development, improves code readability, and provides better tooling support.

FeatureDynamic (JavaScript)Static (TypeScript)
Type ErrorsDetected at runtimeDetected at compile-time
Refactoring SafetyRisky without good testsSafer, thanks to type checking
IDE SupportBasic autocompleteRich intellisense and error checking
Code DocumentationRequires manual effortTypes act as documentation
Team CollaborationMore prone to bugs and miscommunicationTypes and or interfaces help define expectations

Typed languages help you catch errors early, improve tooling, and reduce ambiguity in your code, but most importantly, makes it easer to scale apps without making breaking-changes onto production. And with TypeScript, you don’t need to give up the flexibility of JavaScript—you enhance it.

Of course, since this is only a superset of Javascript, you’re not actually making javascript static at runtime, you can make the same bad practices/mistakes that you would with javascript, the only diffence is that you’ll get feedback on those while writing the code by the compiler.


Where to Start with TypeScript

Getting started is straightforward:

  1. Install TypeScript globally:

    npm install -g typescript
  2. Initialize a TypeScript project:

    tsc --init
  3. Write your first file:

    Create a “hello.ts” file:

    function greet(name: string): void {
      console.log(`Hello, ${name}!`);
    }
    greet("World");
  4. Compile it to JavaScript:

    tsc hello.ts
  5. Run the output “hello.js” with Node.js or in the browser.


Useful TypeScript Features

1. Types & Interfaces

Types and interfaces define the shape of data, allowing for better code contracts.

type User = {
  id: number;
  name: string;
  email?: string; // Optional property
};

interface Product {
  id: string;
  name: string;
  price: number;
}

function printUser(user: User) {
  console.log(user.name);
}

Use “type” for unions, primitives, and more complex compositions. Use “interface” when you expect the structure to be extended. Here’s an article about it: Interface vs Type – A Comprehensive Guide


2. Generics

Generics allow you to write flexible and reusable components.

function identity<T>(value: T): T {
  return value;
}

const num = identity<number>(42);
const str = identity<string>("hello");

While this being a really loose example, this tool is powerful for functions, classes, and data structures where the type isn’t known up front.

If you want to learn more about it, here’s an article that explains everything aboyt generics in Typescript:

Understanding Typescript Generics

3. Decorators (Experimental)

Decorators are a powerful meta-programming feature. They allow you to annotate classes, methods, and properties with reusable behaviors.

function Log(target: any, key: string, descriptor: Property) {
  const original = descriptor.value;
  descriptor.value = function (...args: T[]) {
    console.log(`Calling ${key} with`, args);
    return original.apply(this, args);
  };
}

class Calculator {
  @Log
  add(a: number, b: number): number {
    return a + b;
  }
}

This pattern is also found in typed languages like C# and Java, however, you can also find this pattern in Python.

You’ll need to enable decorators in your “tsconfig.json”:

{ "experimentalDecorators": true }

Learning Resources

Official TypeScript Handbook TypeScript Deep Dive tsconfig Reference

Take into account..

Like I wrote before many… many times, this is only a superset of javascript, so the original language wasn’t supposed to work as a typed-static language, making some times inevitable the use of the “any” or “unknown” keywords.


const random_val: any = get_random_value();
const unkown_val: unknown = get_unknown_value();

Of course, this is a really stupid example, and the best practice is to prevent using them, but it can happen in the wild.

When I was starting out, my first professional typescript project was filled with those mistakes, here’s an excerpt:

let result: any = [];
let levelOfDepth: any = 0;
for (const man of divisions) {
    levelOfDepth = _.isUndefined(man.level) ? 0 : man.level;
    result = [...result, ...getLevel(byManager, man, levelOfDepth)];
}

let resultRev = result.slice().reverse();
let resultFilttered = resultRev.filter(function (elem: any, index: any, self: any) {
    return index == self.indexOf(elem);
});

let finalResult = resultFilttered.slice().reverse();
finalResult = finalResult.filter(function (elem: any, index: any, self: any) {
    return index == self.indexOf(elem);
});

let endResult: any

What the fuck is that? What was I thinking?

Also, not that it makes it better, but I changed some of the naming to some variables on that code for NDA reasons.

Conclusion

TypeScript gives you the best of both worlds: the freedom of JavaScript with the safety of types. As your projects and teams grow, the clarity, tooling, and confidence that TypeScript provides become invaluable.

You don’t have to go all-in immediately—start small, incrementally adopt types, maybe at some point you learn .TSX as well (That’s how a big part of my TS knowledge came from).

You may like: