Last updated: 2026-05-05

Basic types

TypeScript provides strict types to ensure variables always hold the expected values. These basic types are essentially JavaScript primitive data types used as "rules" to dictate what a variable can contain.


Basic Types

Below is a list of the safe types used to prevent errors in your code:

TypeExampleDescription
numberlet age: number = 25;Must be an integer or decimal value.
stringlet name: string = "Ali";Must be a text value.
booleanlet isTrue: boolean = true;Must be either true or false.
nulllet empty: null = null;Explicitly represents "nothing."
undefinedlet x: undefined;For uninitialized variables.
bigintlet big: bigint = 100n;For integers larger than the standard number type.
symbollet id: symbol = Symbol();Unique identifiers for objects.

Type Annotations vs. Type Inference

Type Annotations

Explicitly defining what data type a variable must hold. If you attempt to assign the wrong type, TypeScript throws an error immediately.

let username: string = "Ahmed";
let age: number = 30;

Type Inference

If you do not provide an explicit type, TypeScript automatically "guesses" (infers) the type based on the value you first assigned.

let city = "Lagos"; // TypeScript infers this is a 'string'
city = 123;         // ❌ Error: Type 'number' is not assignable to 'string'

Special Types

These types are used when the data type might be dynamic or unknown.

  • any: Allows literally any data type. Using any effectively turns off TypeScript's safety features, so it is generally advisable to avoid it.
  • unknown: Similar to any in that you can assign any value to an unknown variable. However, you cannot assign an unknown variable to a typed variable without first checking and narrowing its type. This makes it the safer choice over any when the type is genuinely uncertain.
let randomValue: any = 10;
randomValue = "Hello"; // ✅ No error — any accepts everything

let value: unknown = "Hello";
let num: number = value; // ❌ Error: Type 'unknown' is not assignable to 'number'
                         // You must first check the type before assigning it

Union Types

A Union Type allows a variable to accept two or more specific types. This is useful when a value could legitimately be one of several types (e.g., an ID that could be a string or a number).

let score: number | string;

score = 100;  // ✅ Allowed
score = "A+"; // ✅ Allowed
score = true; // ❌ Error: Type 'boolean' is not assignable to 'number | string'

Type Narrowing

When working with union types, you often need to narrow the type before performing specific operations like math or string manipulation. Narrowing means using a conditional check to tell TypeScript which specific type you are working with at that point in the code.

The most common way to narrow is with a typeof check inside an if statement:

let score: number | string;
score = 100;

if (typeof score === "number") {
  console.log(score * 2);      // ✅ Safe — TypeScript knows it's a number here
} else {
  console.log(score.toUpperCase()); // ✅ Safe — TypeScript knows it's a string here
}

Without narrowing, TypeScript will not allow you to call number-only or string-only methods on a union type, because it cannot guarantee which type the variable holds at runtime.