TechLead
Lesson 2 of 8
5 min read
TypeScript

Basic Types

Master TypeScript's primitive types, arrays, tuples, enums, and special types

Primitive Types

TypeScript includes all JavaScript primitives plus additional type annotations.

// String
let firstName: string = "Alice";
let greeting: string = `Hello, ${firstName}`;

// Number (integers and floats)
let age: number = 30;
let price: number = 19.99;
let hex: number = 0xff;
let binary: number = 0b1010;

// Boolean
let isActive: boolean = true;
let hasPermission: boolean = false;

// Null and Undefined
let nothing: null = null;
let notDefined: undefined = undefined;

// BigInt (ES2020+)
let bigNumber: bigint = 9007199254740991n;

// Symbol
let uniqueKey: symbol = Symbol("key");

Arrays

// Two ways to declare arrays
let numbers: number[] = [1, 2, 3, 4, 5];
let strings: Array<string> = ["a", "b", "c"];

// Mixed arrays (avoid when possible)
let mixed: (string | number)[] = [1, "two", 3];

// Readonly arrays
let readonlyNumbers: readonly number[] = [1, 2, 3];
// readonlyNumbers.push(4); // Error: Property 'push' does not exist

// Array methods are type-aware
const doubled = numbers.map(n => n * 2);  // number[]
const filtered = strings.filter(s => s.length > 1);  // string[]

Tuples

Fixed-length arrays with specific types at each position:

// Tuple: [string, number]
let person: [string, number] = ["Alice", 30];

// Accessing tuple elements
const name = person[0];  // string
const age = person[1];   // number

// Tuple with optional element
let optionalTuple: [string, number?] = ["Bob"];

// Tuple with rest elements
let flexibleTuple: [string, ...number[]] = ["scores", 90, 85, 92];

// Named tuples (TypeScript 4.0+)
type Point = [x: number, y: number];
let coordinates: Point = [10, 20];

// Readonly tuple
const readonlyTuple: readonly [string, number] = ["Alice", 30];
// readonlyTuple[0] = "Bob"; // Error!

Enums

// Numeric enum (default)
enum Direction {
  Up,      // 0
  Down,    // 1
  Left,    // 2
  Right    // 3
}

let move: Direction = Direction.Up;
console.log(Direction.Up);    // 0
console.log(Direction[0]);    // "Up"

// String enum
enum Status {
  Pending = "PENDING",
  Active = "ACTIVE",
  Completed = "COMPLETED",
  Cancelled = "CANCELLED"
}

let orderStatus: Status = Status.Active;

// Const enum (inlined at compile time)
const enum HttpStatus {
  OK = 200,
  NotFound = 404,
  ServerError = 500
}

// Heterogeneous enum (avoid)
enum Mixed {
  No = 0,
  Yes = "YES"
}

Any, Unknown, Never, Void

// any - disables type checking (avoid!)
let anything: any = 42;
anything = "string";
anything = true;
anything.nonExistentMethod(); // No error, but crashes at runtime

// unknown - type-safe any
let uncertain: unknown = 42;
uncertain = "string";
// uncertain.toUpperCase(); // Error! Must check type first

if (typeof uncertain === "string") {
  console.log(uncertain.toUpperCase()); // OK
}

// void - function returns nothing
function logMessage(msg: string): void {
  console.log(msg);
  // no return statement
}

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

function infiniteLoop(): never {
  while (true) {}
}

Object Type

// Inline object type
let user: { name: string; age: number } = {
  name: "Alice",
  age: 30
};

// Optional properties
let config: { host: string; port?: number } = {
  host: "localhost"
  // port is optional
};

// Readonly properties
let point: { readonly x: number; readonly y: number } = {
  x: 10,
  y: 20
};
// point.x = 30; // Error!

// Index signatures
let dictionary: { [key: string]: number } = {
  apple: 1,
  banana: 2,
  cherry: 3
};
dictionary["date"] = 4;  // OK

Type Assertions

// Type assertion (you know more than TypeScript)
let someValue: unknown = "Hello, World!";

// Using 'as' syntax (preferred)
let strLength: number = (someValue as string).length;

// Using angle-bracket syntax (not in JSX)
let strLength2: number = (<string>someValue).length;

// DOM element assertion
const input = document.getElementById("myInput") as HTMLInputElement;
input.value = "Hello";

// Non-null assertion (use carefully!)
let maybeString: string | null = getValue();
let definitelyString: string = maybeString!;  // Assert it's not null

Literal Types

// String literal types
let direction: "north" | "south" | "east" | "west";
direction = "north";  // OK
// direction = "up";  // Error!

// Numeric literal types
let diceRoll: 1 | 2 | 3 | 4 | 5 | 6;
diceRoll = 3;  // OK
// diceRoll = 7;  // Error!

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

// Combining with other types
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";

function makeRequest(url: string, method: HttpMethod) {
  // ...
}

makeRequest("/api/users", "GET");  // OK
// makeRequest("/api/users", "PATCH");  // Error!

Avoid 'any'

Using any defeats the purpose of TypeScript. Instead:

  • • Use unknown when you don't know the type
  • • Use generics for flexible but type-safe code
  • • Use union types for multiple possibilities

Key Takeaways

  • • Use primitive types: string, number, boolean
  • • Arrays can be typed with type[] or Array<type>
  • • Tuples are fixed-length typed arrays
  • • Enums provide named constants
  • • Prefer unknown over any
  • • Literal types restrict to specific values

Continue Learning