TypeScript provides several basic types that correspond to JavaScript's primitive types and more.

Primitive Types

number

Represents both integers and floating-point numbers.

let age: number = 25;
let price: number = 19.99;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;

string

Represents text data.

let name: string = "Alice";
let greeting: string = `Hello, ${name}!`; // Template literals
let message: string = 'Single quotes work too';

boolean

Represents true or false.

let isActive: boolean = true;
let isComplete: boolean = false;

Special Types

any

Disables type checking. Use sparingly!

let value: any = 42;
value = "hello";      // OK
value = true;         // OK
value.foo.bar.baz();  // No error (but might crash at runtime!)

unknown

Type-safe alternative to any. Must check type before use.

let value: unknown = 42;

// value.toFixed(); // ❌ Error: Object is of type 'unknown'

if (typeof value === "number") {
  value.toFixed(2); // ✅ OK, we've narrowed the type
}

void

Represents the absence of a value. Used for functions that don't return.

function logMessage(message: string): void {
  console.log(message);
  // No return statement
}

null and undefined

let u: undefined = undefined;
let n: null = null;

// With strictNullChecks enabled:
let num: number = null;        // ❌ Error
let str: string = undefined;   // ❌ Error

never

Represents values that never occur. Used for functions that never return.

function throwError(message: string): never {
  throw new Error(message);
}

function infiniteLoop(): never {
  while (true) {
    // Never returns
  }
}

Type Inference

TypeScript can often infer types automatically.

// TypeScript infers: let count: number
let count = 42;

// TypeScript infers: let name: string
let name = "Alice";

// TypeScript infers: let isActive: boolean
let isActive = true;

Type Annotations

Explicitly specify types when needed.

// Explicit type annotation
let age: number = 25;

// Type annotation without initial value
let username: string;
username = "alice";

// Multiple variables
let x: number, y: number, z: number;

Literal Types

A literal type is a type that represents a single value.

// String literal types
let direction: "up" | "down" | "left" | "right" = "up";

// Number literal types
let diceRoll: 1 | 2 | 3 | 4 | 5 | 6 = 4;

// Boolean literal types
let isTrue: true = true;

Type Aliases

Create custom names for types.

type Age = number;
type Name = string;
type ID = string | number;

let userAge: Age = 25;
let userName: Name = "Alice";
let userId: ID = "123";

Exercises

Exercise 1: Basic Types

// TODO: Add proper type annotations
let myAge = 30;
let myName = "Bob";
let isStudent = true;
let favoriteNumber = 7;

Exercise 2: Type Inference

// What types does TypeScript infer for these?
let a = 10;
let b = "hello";
let c = true;
let d = null;

Exercise 3: Literal Types

// Create a type for HTTP status codes: 200, 404, 500
// Create a variable that can only be one of these values

Exercise 4: Type Aliases

// Create type aliases for:
// - Email (string)
// - PhoneNumber (string)
// - UserID (number)
// Then create a user object using these types

Common Pitfalls

  1. Using any too liberally
    → Defeats the purpose of TypeScript. Use unknown instead.

  2. Not using type inference
    → TypeScript can infer many types. Don't over-annotate.

  3. Confusing null and undefined
    null is an intentional absence, undefined means not set.

Next Steps

Learn about Variables and Type Annotations.