TS

TypeScript Fundamentals

17 lessons

Progress0%
1. Introduction to TypeScript
1What is TypeScript?2Setting Up TypeScript
2. Basic Types
1Primitive Types2Interfaces and Type Aliases
3. Functions and Generics
Typed FunctionsGenerics
4. Classes and OOP
ClassesInheritance and Interfaces
5. Advanced Types
Union and Intersection TypesUtility Types
6. Modules and Decorators
ES Modules
7. Decorators
Class & Method DecoratorsProperty & Parameter Decorators
8. Declaration Files
Writing .d.ts Files@types & DefinitelyTyped
9. Advanced Patterns
Conditional Types & inferTemplate Literal Types & satisfies
All Tutorials
TypeScriptFunctions and Generics
Lesson 6 of 17 min
Chapter 3 · Lesson 2

Generics

Generics in TypeScript

Generics let you write reusable code that works with any type while still maintaining full type safety.

Generic functions A type parameter (e.g., <T>) acts as a placeholder that TypeScript fills in from context:

ts
function identity<T>(value: T): T { return value; }

Generic interfaces and types Parameterise interfaces the same way:

ts
interface Box<T> { contents: T; }

Generic constraints with extends Restrict what types a type parameter can be:

ts
function getLength<T extends { length: number }>(value: T): number { return value.length; }

This lets you access .length safely without widening T to any.

keyof constraint Use keyof to constrain a type parameter to the keys of another type:

ts
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; }

Key concepts:

  • Type inference means you rarely need to supply type arguments explicitly.
  • Multiple type parameters are separated by commas: <T, U>.
  • Constraints narrow what you can accept, but widen what operations you can perform safely inside the function.

Code Examples

Generic function and interfacetypescript
interface Pair<A, B> {
  first: A;
  second: B;
}

function makePair<A, B>(first: A, second: B): Pair<A, B> {
  return { first, second };
}

const p = makePair("age", 30);
console.log(p.first, p.second);

const q = makePair(true, [1, 2, 3]);
console.log(q.first, q.second);

TypeScript infers A and B from the arguments, so you get full type safety without writing type arguments manually.

Constraints with extends and keyoftypescript
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const user = { name: "Alice", age: 30, active: true };
console.log(getProperty(user, "name"));
console.log(getProperty(user, "age"));

function longest<T extends { length: number }>(a: T, b: T): T {
  return a.length >= b.length ? a : b;
}

console.log(longest("hello", "hi"));
console.log(longest([1, 2, 3], [4, 5]));

keyof T produces a union of the literal key names, preventing access of non-existent properties at compile time.

Quick Quiz

1. What does `<T extends { length: number }>` mean?

2. What does `keyof T` produce?

Was this lesson helpful?

PreviousNext