Creating generic functions in TypeScript (TS) and TypeORM enables code to be more reusable while maintaining strong typing. Below, I will demonstrate an example of how to implement generic functions in TypeORM using TS for common operations on database entities.
Example: Creating a Generic CRUD Operation Function
-
Define a Generic Interface
First, we define a generic interface that specifies methods all entities must implement. This provides a consistent approach for handling various entities.
typescriptinterface IGenericCRUD<T> { create(item: T): Promise<T>; read(id: number): Promise<T | null>; update(id: number, item: T): Promise<T>; delete(id: number): Promise<void>; } -
Implement the Generic Class
Next, we define a generic class implementing the
IGenericCRUDinterface. This class leverages TypeORM's Repository to execute CRUD operations.typescriptimport { Repository, EntityTarget, getRepository } from 'typeorm'; class GenericCRUD<T> implements IGenericCRUD<T> { private entity: EntityTarget<T>; private repo: Repository<T>; constructor(entity: EntityTarget<T>) { this.entity = entity; this.repo = getRepository(this.entity); } async create(item: T): Promise<T> { return this.repo.save(item); } async read(id: number): Promise<T | null> { return this.repo.findOne(id); } async update(id: number, item: T): Promise<T> { await this.repo.update(id, item); return this.read(id); } async delete(id: number): Promise<void> { await this.repo.delete(id); } } -
Use the Generic Class
Now we can instantiate CRUD operations for specific entity types. For instance, with a
Userentity, we use it as follows:typescriptimport { User } from './entities/User'; const userCRUD = new GenericCRUD<User>(User); async function demoUserCRUD() { // Create user const newUser = await userCRUD.create({ firstName: "Xiao", lastName: "Ming" }); // Read user const user = await userCRUD.read(newUser.id); // Update user information const updatedUser = await userCRUD.update(user.id, { ...user, lastName: "Li" }); // Delete user await userCRUD.delete(updatedUser.id); }
Summary
By utilizing generics, we can create a strongly typed and reusable CRUD class compatible with any TypeORM entity. This approach not only minimizes code duplication but also enhances maintainability and type safety.