Typescript Foundations / Generics

Using generics with arrays and promises

✅ Why use generics with arrays?

Generic arrays let you define what type of elements the array holds, ensuring type safety while keeping flexibility.

🔸 Syntax Options

const numbers: Array<number> = [1, 2, 3];   // Generic form
const names: string[] = ["Alice", "Bob"];  // Shorthand form

Both are valid — the first one is more explicitly generic.

🔸 Generic Function Working with Arrays

function getFirstElement<T>(arr: T[]): T {
  return arr[0];
}

const firstNum = getFirstElement<number>([10, 20, 30]);  // T = number
const firstStr = getFirstElement(["a", "b", "c"]);       // T = string

✅ Why use generics with promises?

Generics allow you to explicitly define the type a promise resolves to, helping TypeScript infer the correct return type after await or .then().

🔸 Example: Promise with a Generic Type

function fetchData<T>(url: string): Promise<T> {
  return fetch(url).then(res => res.json());
}

// Define the expected type
interface User {
  id: number;
  name: string;
}

fetchData<User>("<https://api.example.com/user/1>")
  .then(user => {
    console.log(user.name);  // user is of type User
  });
}

🔸 async/await with Generic Promises

async function getUser<T>(id: number): Promise<T> {
  const res = await fetch(`/api/users/${id}`);
  return await res.json();
}

interface Admin {
  id: number;
  role: string;
}

async function main() {
  const admin = await getUser<Admin>(1);
  console.log(admin.role);
}


🧠 Summary

Feature

Example

Generic Array

Array<T> or T[]

Function with array

function<T>(arr: T[]): T

Generic Promise

Promise<T>

fetchData<T>()

Strongly typed API responses