P
Prisma2w ago
Consii

Nestjs Prisma Client Extension for Soft Delete in v7 with type-safety

How can I setup properly the soft delete extension after migrating to v7 with type-safety? I am using this ext. https://github.com/olivierwilkinson/prisma-extension-soft-delete It has type-safety before, but right now it gives me an 'any' type when using it on my services.
import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@src/generated/client';
import { createSoftDeleteExtension } from 'prisma-extension-soft-delete';

@Injectable()
export class DatabaseService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
async softDelete() {
return this.$extends(
createSoftDeleteExtension({
models: { [models here] },
defaultConfig: {
field: 'deletedAt',
createValue: (deleted) => (deleted ? new Date() : null),
allowToOneUpdates: true,
},
}),
);
}

async onModuleInit() {
return await this.$connect();
}

async onModuleDestroy() {
return await this.$disconnect();
}
}
import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@src/generated/client';
import { createSoftDeleteExtension } from 'prisma-extension-soft-delete';

@Injectable()
export class DatabaseService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
async softDelete() {
return this.$extends(
createSoftDeleteExtension({
models: { [models here] },
defaultConfig: {
field: 'deletedAt',
createValue: (deleted) => (deleted ? new Date() : null),
allowToOneUpdates: true,
},
}),
);
}

async onModuleInit() {
return await this.$connect();
}

async onModuleDestroy() {
return await this.$disconnect();
}
}
GitHub
GitHub - olivierwilkinson/prisma-extension-soft-delete: Prisma exte...
Prisma extension for adding soft delete to Prisma models, even when using nested queries - GitHub - olivierwilkinson/prisma-extension-soft-delete: Prisma extension for adding soft delete to Prisma...
No description
No description
3 Replies
Prisma AI Help
You opted for speed from this bot. Let's conjure up an answer right now! To achieve type-safe soft delete extensions with Prisma v7 and NestJS, you need to ensure that your extended Prisma client is properly typed. The main issue is that calling $extends at runtime (as in your softDelete() method) returns a client of type any unless you capture the type at the point of extension and use that type throughout your app. Recommended Approach: 1. Extend the client once, outside the service class, and use the extended type everywhere.
This is the pattern recommended by the Prisma team and the community for type-safety in NestJS. Here’s how you can do it:
// prisma-extended-client.ts
import { PrismaClient } from '@src/generated/client';
import { createSoftDeleteExtension } from 'prisma-extension-soft-delete';

export const ExtendedPrismaClient = PrismaClient.$extends(
createSoftDeleteExtension({
models: { /* your models here */ },
defaultConfig: {
field: 'deletedAt',
createValue: (deleted) => (deleted ? new Date() : null),
allowToOneUpdates: true,
},
})
);
// prisma-extended-client.ts
import { PrismaClient } from '@src/generated/client';
import { createSoftDeleteExtension } from 'prisma-extension-soft-delete';

export const ExtendedPrismaClient = PrismaClient.$extends(
createSoftDeleteExtension({
models: { /* your models here */ },
defaultConfig: {
field: 'deletedAt',
createValue: (deleted) => (deleted ? new Date() : null),
allowToOneUpdates: true,
},
})
);
// database.service.ts
import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { ExtendedPrismaClient } from './prisma-extended-client';

@Injectable()
export class DatabaseService extends ExtendedPrismaClient implements OnModuleInit, OnModuleDestroy {
async onModuleInit() {
await this.$connect();
}
async onModuleDestroy() {
await this.$disconnect();
}
}
// database.service.ts
import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { ExtendedPrismaClient } from './prisma-extended-client';

@Injectable()
export class DatabaseService extends ExtendedPrismaClient implements OnModuleInit, OnModuleDestroy {
async onModuleInit() {
await this.$connect();
}
async onModuleDestroy() {
await this.$disconnect();
}
}
2. Why this works:
By extending the client outside the service and using the resulting type, you preserve all type information from the extension. This is the same approach used for other extensions and is confirmed to work for type-safety in NestJS with Prisma v5+ and v7, as shown in community solutions and official recommendations see example. 3. Avoid calling $extends inside methods
Doing so loses type informat ion and results in any types, as you’ve experienced. Summary:
Move your extension logic outside the service, export the extended client, and have your service extend that. This will restore type-safety for your soft delete extension in Prisma v7 with NestJS. If you need more advanced patterns (e.g., dependency injection of the extension), see the linked community solutions for further ideas see here.
Consii
ConsiiOP2w ago
Nvm, I just removed the extension because I think it doesn't match the current version of Prisma v7
Nurul
Nurul2w ago
I believe the 'prisma-extension-soft-delete' extension would not be compatible with v7 yet

Did you find this page helpful?