KRYZO.

· TypeScript guide · 8 min read

TypeScript for Beginners

TypeScript adds types to JavaScript so mistakes are caught before the code ever runs. Start here.

TypeScript source file with typed function signatures in a code editor

JavaScript is flexible. That flexibility is a strength until a typo in a property name or a wrong argument type silently breaks a feature in production. TypeScript adds an optional type layer on top of JavaScript to catch those mistakes while you write code.

It is not a different language to learn from scratch. Every valid JavaScript file is already close to valid TypeScript, and you can add types gradually.

What TypeScript is and how it compiles

Browsers and Node.js run JavaScript, not TypeScript. A compiler strips the type annotations away and produces plain JavaScript that any runtime can execute. If the types do not line up, the compiler reports an error before you ever open a browser.

This means the types disappear at runtime and add no cost to the shipped code. They exist to help you and your editor, not the machine.

Basic types and inference

TypeScript understands the common types: string, number, boolean, arrays and objects. In most cases you do not need to write the type at all, because it infers the type from the value you assign.

let title = "Dashboard";
title = 42; // Error: number is not assignable to string

const tags = ["css", "html"];
tags.push("grid");
tags.push(true); // Error: boolean is not assignable to string

Inference keeps code clean while still protecting you. You annotate only where a value has no obvious initial form, such as a function parameter.

Typing function parameters and return values

Function boundaries are where types pay off most. Describing the inputs and the return value documents the function and prevents callers from passing the wrong thing.

function formatPrice(amount: number, currency: string): string {
  return `${currency}${amount.toFixed(2)}`;
}

formatPrice("ten", "USD"); // Error: string is not assignable to number

The return type is often inferred, so the : string is optional, but it makes the contract explicit and catches mistakes inside the function body.

Interfaces and object shapes

An interface names the shape of an object. It is the clearest way to describe the data your app passes around.

interface User {
  id: number;
  name: string;
  email: string;
}

function greet(user: User): string {
  return `Hello, ${user.name}`;
}

Once a value is typed as User, the editor autocompletes its properties and flags any misspelled field immediately.

Unions and optional properties

Real data is rarely uniform. A union lets a value be one of several types, and the question mark marks a property that may be absent.

interface Task {
  id: number;
  title: string;
  completed: boolean;
  dueDate?: string;
  status: "todo" | "doing" | "done";
}

The dueDate may be missing, so TypeScript forces you to check for it before use. The status field can only ever be one of the three listed strings, which removes a whole class of typos.

Where generics fit in

A generic lets a function or interface work with many types while keeping the relationship between input and output. A wrapper around an API response is a common example.

interface ApiResponse<T> {
  data: T;
  status: number;
}

function unwrap<T>(response: ApiResponse<T>): T {
  return response.data;
}

You do not need generics every day, but recognising the angle-bracket syntax makes library types far less intimidating.

Turning on strict mode

TypeScript is most valuable when its strictest checks are active. In tsconfig.json, enabling strict turns on a group of checks including strict null handling, which is where many real bugs hide.

{
  "compilerOptions": {
    "strict": true,
    "target": "ES2020",
    "module": "ESNext"
  }
}

Start with strict on a new project. It is much easier than adding it later, and it is the single setting that gives the most confidence that your types are telling the truth.

Back to all blogs