Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Oppiskele Generic Repository Pattern | Advanced Type Patterns and Best Practices
Working with Interfaces and Generics in TypeScript

bookGeneric Repository Pattern

The repository pattern is a design approach used to manage collections of objects in a consistent and abstract manner. By acting as a mediator between the data source and the rest of your application, a repository provides a simple interface for adding, retrieving, and searching for items. This pattern helps you separate concerns, making your code easier to maintain, test, and scale. With TypeScript, you can combine interfaces and generics to create repositories that work with any type of data, ensuring both flexibility and strong type safety.

123456
// Define a generic interface for a repository interface Repository<T> { add(item: T): void; getAll(): T[]; findById(id: number): T | undefined; }
copy

Suppose you want to manage collections of users and products. With a generic Repository<T>, you can create specific repositories for each type without duplicating code. Consider these simple User and Product types, and their corresponding repository implementations:

12345678910111213141516171819202122232425262728293031323334353637383940414243
// 1. Define a generic interface for a repository interface Repository<T> { add(item: T): void; getAll(): T[]; findById(id: number): T | undefined; } // 2. Define types for User and Product type User = { id: number; name: string }; type Product = { id: number; title: string }; // 3. Create a single generic repository class class GenericRepository<T extends { id: number }> implements Repository<T> { private items: T[] = []; add(item: T): void { this.items.push(item); } getAll(): T[] { return this.items; } findById(id: number): T | undefined { return this.items.find((item) => item.id === id); } } // 4. Use the repository for Users and Products const userRepo = new GenericRepository<User>(); userRepo.add({ id: 1, name: "Alice" }); userRepo.add({ id: 2, name: "Bob" }); const productRepo = new GenericRepository<Product>(); productRepo.add({ id: 101, title: "Laptop" }); productRepo.add({ id: 102, title: "Phone" }); // 5. Display results console.log("All users:", userRepo.getAll()); console.log("User #2:", userRepo.findById(2)); console.log("All products:", productRepo.getAll()); console.log("Product #101:", productRepo.findById(101));
copy
  • With a generic repository interface, you avoid code duplication;
  • Each repository class provides methods for adding, retrieving, and searching for items;
  • TypeScript enforces that only the correct type of object can be added or retrieved from each repository.

By combining generics and interfaces, you can design reusable and scalable code structures. The Repository<T> interface defines a contract that any repository must follow, while generics allow you to specify the type of objects being managed. This means you can create repositories for any data type without rewriting logic, reducing code duplication and making your application easier to extend and maintain.

question mark

Which of the following is a key benefit of combining generics and interfaces in the repository pattern?

Select the correct answer

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 3. Luku 2

Kysy tekoälyä

expand

Kysy tekoälyä

ChatGPT

Kysy mitä tahansa tai kokeile jotakin ehdotetuista kysymyksistä aloittaaksesi keskustelumme

Suggested prompts:

Can you explain how generics improve type safety in this example?

What are some real-world scenarios where the repository pattern is especially useful?

Can you show how to extend the repository to support updating or deleting items?

Awesome!

Completion rate improved to 9.09

bookGeneric Repository Pattern

Pyyhkäise näyttääksesi valikon

The repository pattern is a design approach used to manage collections of objects in a consistent and abstract manner. By acting as a mediator between the data source and the rest of your application, a repository provides a simple interface for adding, retrieving, and searching for items. This pattern helps you separate concerns, making your code easier to maintain, test, and scale. With TypeScript, you can combine interfaces and generics to create repositories that work with any type of data, ensuring both flexibility and strong type safety.

123456
// Define a generic interface for a repository interface Repository<T> { add(item: T): void; getAll(): T[]; findById(id: number): T | undefined; }
copy

Suppose you want to manage collections of users and products. With a generic Repository<T>, you can create specific repositories for each type without duplicating code. Consider these simple User and Product types, and their corresponding repository implementations:

12345678910111213141516171819202122232425262728293031323334353637383940414243
// 1. Define a generic interface for a repository interface Repository<T> { add(item: T): void; getAll(): T[]; findById(id: number): T | undefined; } // 2. Define types for User and Product type User = { id: number; name: string }; type Product = { id: number; title: string }; // 3. Create a single generic repository class class GenericRepository<T extends { id: number }> implements Repository<T> { private items: T[] = []; add(item: T): void { this.items.push(item); } getAll(): T[] { return this.items; } findById(id: number): T | undefined { return this.items.find((item) => item.id === id); } } // 4. Use the repository for Users and Products const userRepo = new GenericRepository<User>(); userRepo.add({ id: 1, name: "Alice" }); userRepo.add({ id: 2, name: "Bob" }); const productRepo = new GenericRepository<Product>(); productRepo.add({ id: 101, title: "Laptop" }); productRepo.add({ id: 102, title: "Phone" }); // 5. Display results console.log("All users:", userRepo.getAll()); console.log("User #2:", userRepo.findById(2)); console.log("All products:", productRepo.getAll()); console.log("Product #101:", productRepo.findById(101));
copy
  • With a generic repository interface, you avoid code duplication;
  • Each repository class provides methods for adding, retrieving, and searching for items;
  • TypeScript enforces that only the correct type of object can be added or retrieved from each repository.

By combining generics and interfaces, you can design reusable and scalable code structures. The Repository<T> interface defines a contract that any repository must follow, while generics allow you to specify the type of objects being managed. This means you can create repositories for any data type without rewriting logic, reducing code duplication and making your application easier to extend and maintain.

question mark

Which of the following is a key benefit of combining generics and interfaces in the repository pattern?

Select the correct answer

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 3. Luku 2
some-alt