TypeScript extends JavaScript with a rich type system. This chapter covers the types you will use most often.

Primitive Types

TypeScript supports the same primitives as JavaScript, with explicit annotations:

  let title: string = 'JS Code Camp';
let count: number = 42;
let isActive: boolean = true;
let nothing: null = null;
let notDefined: undefined = undefined;

// bigint and symbol (ES2020+)
let big: bigint = 100n;
let id: symbol = Symbol('id');
  

Type Inference

When you assign a value, TypeScript often infers the type automatically:

  let city = 'Seattle';   // inferred as string
city = 'Portland';      // OK
// city = 123;          // Error

const PI = 3.14159;     // inferred as number, readonly by const
  

Explicit annotations are useful when there is no initial value or you want a wider type:

  let input: string;  // no initializer — annotation required
input = 'hello';
  

Arrays

Two equivalent syntaxes for arrays:

  let scores: number[] = [90, 85, 88];
let names: Array<string> = ['Alice', 'Bob'];

// Readonly arrays prevent mutation
const tags: readonly string[] = ['js', 'ts'];
// tags.push('node'); // Error
  

Tuples

Tuples are fixed-length arrays where each position has a known type:

  let pair: [string, number] = ['Alice', 25];
let rgb: [number, number, number] = [255, 128, 0];

let point: [number, number] = [10, 20];
  

Access tuple elements by index — TypeScript knows the type at each position:

  const [name, age] = pair;
console.log(name.toUpperCase()); // string methods available
console.log(age.toFixed(1));     // number methods available
  

Enums

Enums assign names to numeric or string constants:

  enum Direction {
    Up,
    Down,
    Left,
    Right
}

let heading: Direction = Direction.Up;
console.log(heading); // 0

enum Status {
    Pending = 'PENDING',
    Active = 'ACTIVE',
    Done = 'DONE'
}

function setStatus(s: Status) {
    console.log(s);
}

setStatus(Status.Active); // "ACTIVE"
  

String enums produce readable values at runtime. Many teams prefer union types instead (covered later).

any, unknown, and never

  let flexible: any = 'hello';
flexible = 42;           // no error — avoid any in production code

let userInput: unknown = getData();
// Must narrow before use:
if (typeof userInput === 'string') {
    console.log(userInput.toUpperCase());
}

function fail(msg: string): never {
    throw new Error(msg);  // never returns
}
  

Use unknown instead of any when the type is not yet known — it forces you to check before use.

Object Types

Inline object type annotations describe shape:

  let user: { name: string; age: number; email?: string } = {
    name: 'Alice',
    age: 30
};

user.email = '[email protected]'; // optional property
  

For reusable shapes, prefer interfaces or type aliases — covered in the next chapter.

Summary

Type Example Use case
Primitives string, number, boolean Single values
Arrays number[] Collections
Tuples [string, number] Fixed structure
Enums Status.Active Named constants
unknown Safe alternative to any External input

Next, we apply these types to functions and define object contracts with interfaces.