TypeScript: What, Why and How?!

TypeScript adds static typing on top of JavaScript, catching a real class of bugs at compile time instead of at runtime. The fundamentals here haven’t changed in years, but two specific things in most existing TypeScript guides have: the default target in a new project’s tsconfig.json, and how decorators actually work as of TypeScript 5.0. Both are corrected below rather than repeated as they used to be.

In this post: What TypeScript actually adds · Setting up a project · A cheat sheet, with the target fixed · Decorators: the part that actually changed · Linting: ESLint, not TSLint · Where it’s actually used · Related reading


What TypeScript actually adds

Any valid JavaScript is already valid TypeScript — it’s an additive superset, not a separate language to learn from scratch. The core additions worth knowing:

  • Static typing, optional per-variable rather than all-or-nothing, catching type mismatches at compile time instead of as a runtime surprise.
  • Type inference — TypeScript infers a variable’s type from context in most cases, so explicit type annotations are needed less often than a first read of the syntax suggests.
  • Interfaces and generics for describing shapes of data and writing functions/classes that work across multiple types without losing type safety.
  • Enums for named sets of constants, more self-documenting than magic strings or numbers scattered through a codebase.
  • Real tooling: the `tsc` compiler plus IDE-level autocomplete, inline type checking, and refactoring support that plain JavaScript can’t offer to the same degree.

Setting up a project
mkdir my-typescript-project && cd my-typescript-project
npm init -y
npm install -g typescript
mkdir src

A minimal `src/main.ts`:

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

Then compile and run:

tsc
node dist/main.js

The `tsconfig.json` controls how `tsc` compiles — worth getting the `target` value right from the start, covered in the next section, since it’s the single most commonly outdated setting copied from older guides.


“target”: “es5” is genuinely outdated advice now — modern runtimes support ES2020+ natively, and ES5 output means paying a real transpilation cost for compatibility nothing actually needs anymore.

A cheat sheet, with the target fixed

Worth a direct correction on the `tsconfig.json` shown in most older TypeScript guides: `”target”: “es5″` is genuinely outdated now, not just a style preference. Modern browsers and Node.js versions support ES2020+ natively — targeting ES5 means the compiler spends effort transpiling arrow functions, async/await, and other now-universal features into older syntax nothing actually needs anymore. `esnext` or `es2020` is the current, realistic default, adjusted down only if a specific, known-old runtime genuinely requires it:

// Variables, functions, types
let myVar: string = "Hello";
const multiply = (a: number, b: number): number => a * b;
function greet(name: string, greeting: string = "Hello"): void {
    console.log(`${greeting}, ${name}!`);
}

// Arrays, tuples, objects, enums, unions
let myArray: number[] = [1, 2, 3];
let myTuple: [string, number] = ["Hello", 42];
let myObject: { name: string, age: number } = { name: "Alice", age: 30 };
enum Color { Red, Green, Blue }
let myUnion: string | number = "Hello";

// Type aliases and interfaces
type Point = { x: number, y: number };
interface Shape {
    name: string;
    area(): number;
}

// Classes and generics
class Rectangle implements Shape {
    constructor(public name: string, public width: number, public height: number) {}
    area(): number { return this.width * this.height; }
}
function identity(arg: T): T { return arg; }

// tsconfig.json -- current, not the ES5 target most older guides still show
{
    "compilerOptions": {
        "target": "esnext",
        "module": "nodenext",
        "strict": true,
        "outDir": "./dist"
    },
    "include": ["./src/**/*"]
}

Decorators: the part that actually changed

Worth a direct correction here too, since it’s a genuinely common source of confusion in guides written before 2023: TypeScript decorators come in two incompatible flavors, and most older tutorials only show the old one. Legacy decorators — enabled via `experimentalDecorators: true`, predating any finalized JavaScript standard — receive a `(target, key, descriptor)` signature. TC39 standard decorators — the actual current default as of TypeScript 5.0, no flag required — receive a different `(value, context)` signature instead, and don’t support parameter decorators at all.

// Legacy (experimentalDecorators: true) -- (target, key, descriptor)
function legacyLog(target: any, key: string) {
    console.log(`Method ${key} is called.`);
}

// TC39 standard (the current default, no flag needed) -- (value, context)
function log(value: Function, context: ClassMethodDecoratorContext) {
    console.log(`Method ${String(context.name)} is being decorated.`);
    return value;
}

class MyClass {
    @log
    myMethod() {
        // Method implementation
    }
}

The two aren’t interchangeable — a decorator function written for one signature doesn’t work correctly if applied under the other mode, and mixing code written for both inside one project is a real source of confusing runtime errors. Angular and other frameworks with an established codebase predating 2023 may still deliberately run on `experimentalDecorators` for compatibility reasons; a new project should default to the standard, flag-free version unless there’s a specific reason not to.


Linting: ESLint, not TSLint

Worth a direct correction rather than presenting these as two current, equally valid options: TSLint was deprecated back in 2019 and hasn’t seen real development since 2020 — it’s not a live alternative to ESLint, it’s dead tooling that still shows up in older guides. `typescript-eslint` (ESLint plus the `@typescript-eslint/parser` and `@typescript-eslint/eslint-plugin` packages) is the only real, current option for linting TypeScript:

npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin

A project still configured for TSLint isn’t a stylistic holdout — it’s running a linter with no active development, worth migrating off rather than maintaining indefinitely.


Where it’s actually used
  • Angular is built entirely in TypeScript — not optional, not bolted on.
  • React and Vue both offer strong, official TypeScript support, even though neither requires it — most new production React/Vue projects default to TypeScript regardless.
  • Node.js backends — APIs, microservices, CLI tools — benefit from the same compile-time error catching server-side as client-side.
  • Type definitions for libraries (the `@types/*` package ecosystem) let JavaScript-only libraries still get TypeScript’s autocomplete and type checking for consumers.
  • Gradual migration of an existing JavaScript codebase is a real, common path — TypeScript’s superset design means adopting it incrementally, file by file, rather than requiring a rewrite.


The language fundamentals in this cheat sheet are stable and worth learning once — the compiler target, the linting toolchain, and the decorator standard are the three pieces most likely to be quietly out of date in a guide that hasn’t been revisited recently, this one included until now.

App Catalog Authentication Automation Backup Compliance Content Type CSS Flows Google Javascript Limitations List Metadata MFA Microsoft Node NodeJs O365 OneDrive Permissions PnP PnPJS Policy PowerApps Power Automate PowerAutomate PowerPlatform PowerShell React ReactJs Rest API Rest Endpoint Security Send an HTTP Request to SharePoint SharePoint SharePoint List SharePoint Modern SharePoint Online SPFX SPO Sync Tags Teams Termstore Versioning

Leave a Comment

Your email address will not be published. Required fields are marked *