From bf52b546757257d5aa646c94fa3d9c70b09f5b9d Mon Sep 17 00:00:00 2001 From: Ahmed Wael Date: Tue, 13 May 2025 11:07:56 +0300 Subject: [PATCH] feat(sign): add generics to sign ans sign async methods --- lib/jwt.service.spec.ts | 60 +++++++++++++++++++++++++++++++++++++++++ lib/jwt.service.ts | 8 +++--- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/lib/jwt.service.spec.ts b/lib/jwt.service.spec.ts index 67c6fce0..c731dc74 100644 --- a/lib/jwt.service.spec.ts +++ b/lib/jwt.service.spec.ts @@ -378,4 +378,64 @@ describe('JwtService', () => { ); }); }); + + describe('should properly handle generic types', () => { + let jwtService: JwtService; + + // Define an interface for type safety testing + interface UserPayload { + id: number; + username: string; + roles: string[]; + } + + beforeAll(async () => { + jwtService = await setup({ secretOrKeyProvider: undefined }); + }); + + it('should sign with correct interface implementation', () => { + const validPayload: UserPayload = { + id: 1, + username: 'testuser', + roles: ['user', 'admin'] + }; + + // This should pass type checking + const token = jwtService.sign(validPayload); + expect(token).toBeDefined(); + }); + + it('should fail type checking with incorrect interface implementation', () => { + const invalidPayload = { + id: 1, + // Missing username property + roles: ['user'] + }; + + // @ts-expect-error as the username property is not defined in the payload + jwtService.sign(invalidPayload); + }); + + it('should signAsync with correct interface implementation', async () => { + const validPayload: UserPayload = { + id: 1, + username: 'testuser', + roles: ['user', 'admin'] + }; + + const token = await jwtService.signAsync(validPayload); + expect(token).toBeDefined(); + }); + + it('should fail type checking with incorrect interface implementation for signAsync', async () => { + const invalidPayload = { + id: 1, + // Missing username property + roles: ['user'] + }; + + // @ts-expect-error as the username property is not defined in the payload + await jwtService.signAsync(invalidPayload); + }); + }); }); diff --git a/lib/jwt.service.ts b/lib/jwt.service.ts index b5a4952b..d13135f1 100644 --- a/lib/jwt.service.ts +++ b/lib/jwt.service.ts @@ -27,7 +27,8 @@ export class JwtService { payload: string, options?: Omit ): string; - sign(payload: Buffer | object, options?: JwtSignOptions): string; + sign(payload: Buffer, options?: JwtSignOptions): string; + sign(payload: T, options?: JwtSignOptions): string; sign(payload: string | Buffer | object, options?: JwtSignOptions): string { const signOptions = this.mergeJwtOptions( { ...options }, @@ -67,8 +68,9 @@ export class JwtService { payload: string, options?: Omit ): Promise; - signAsync( - payload: Buffer | object, + signAsync(payload: Buffer, options?: JwtSignOptions): Promise; + signAsync( + payload: T, options?: JwtSignOptions ): Promise; signAsync(