В этом уроке мы увидим, как Generic можно использовать в Angular.
Представьте, у нас есть пара модулей в проекте angular. Например, BookMark, Search и Profile — это имена некоторых модулей. Разные модули выполняют разную функциональность. Каждый модуль имеет свою модель и сервис для вызовов API. Все API обычно имеют базовые функции CRUD, такие как поиск, сохранение, обновление и удаление. Все эти модули будут иметь практически одинаковые сервисы.
В этом случае мы можем сделать общий сервис и повторно использовать его для сервисов разных модулей.

Давайте реализуем общий сервис
Создадим интерфейс для обычных операций с творогом:

import { Observable } from 'rxjs/Observable';
export interface CrudOperations<T, ID> {
  save(t: T): Observable<T>;
  update(id: ID, t: T): Observable<T>;
  findOne(id: ID): Observable<T>;
  findAll(): Observable<T[]>;
  delete(id: ID): Observable<any>;
}

Теперь давайте реализуем этот интерфейс как абстрактный класс (экземпляр которого нельзя создать), который будет использоваться в различных сервисах модулей путем расширения абстрактного класса.

import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { CrudOperations } from './crud-operations.interface';
export abstract class CrudService<T, ID> implements CrudOperations<T, ID> {
  constructor(
    protected _http: HttpClient,
    protected _base: string
  ) {}
  save(t: T): Observable<T> {
    return this._http.post<T>(this._base, t);
  }
  update(id: ID, t: T): Observable<T> {
    return this._http.put<T>(this._base + "/" + id, t, {});
  }
  findOne(id: ID): Observable<T> {
    return this._http.get<T>(this._base + "/" + id);
  }
  findAll(): Observable<T[]> {
    return this._http.get<T[]>(this._base)
  }
  delete(id: ID): Observable<T> {
    return this._http.delete<T>(this._base + '/' + id);
  }
}

Теперь давайте воспользуемся универсальной службой в одном из наших модулей
Наша модель данных этого модуля выглядит следующим образом:

export class Bookmark {
  public id: number;
  public url: string;
  public description: string;
}

Теперь наша модульная служба будет расширять универсальную службу, созданную ранее.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Bookmark } from './bookmark.model';
import { CrudService } from './crud.service';
@Injectable()
export class BookmarkService extends CrudService<Bookmark, number> {
  protected BASE_API: string = 'http://localhost:8080/api/bookmarks'
  constructor(protected _http: HttpClient) {
    super(_http, this.BASE_API);
  }
}

Таким образом, мы можем использовать концепцию Generic в Angular.

В следующей части мы увидим использование дженериков в загрузочном приложении JAVA Spring.

Ссылка:
https://jasonwhite.xyz/posts/2019/11/16/angular-8-creating-a-generic-crud-service/