diff --git a/src/TransformOperationExecutor.ts b/src/TransformOperationExecutor.ts index fe1da8e32..ef8deeff9 100644 --- a/src/TransformOperationExecutor.ts +++ b/src/TransformOperationExecutor.ts @@ -117,6 +117,9 @@ export class TransformOperationExecutor { } else if (!!getGlobal().Buffer && (targetType === Buffer || value instanceof Buffer) && !isMap) { if (value === null || value === undefined) return value; return Buffer.from(value); + } else if ((targetType === Uint8Array || value instanceof Uint8Array) && !isMap) { + if (value === null || value === undefined) return value; + return new Uint8Array(value); } else if (isPromise(value) && !isMap) { return new Promise((resolve, reject) => { value.then( diff --git a/test/functional/basic-functionality.spec.ts b/test/functional/basic-functionality.spec.ts index f3d002fdc..d787dc9a1 100644 --- a/test/functional/basic-functionality.spec.ts +++ b/test/functional/basic-functionality.spec.ts @@ -726,6 +726,29 @@ describe('basic functionality', () => { }); }); + it('should preserve Uint8Array values when converting to class instances', () => { + defaultMetadataStorage.clear(); + + class User { + @Type(() => Uint8Array) + bytes: Uint8Array; + } + + const bytes = new Uint8Array([1, 2, 3]); + const fromPlainUser = { bytes }; + + const transformedUser = plainToInstance(User, fromPlainUser); + expect(transformedUser).toBeInstanceOf(User); + expect(transformedUser.bytes).toBeInstanceOf(Uint8Array); + expect(Array.from(transformedUser.bytes)).toEqual([1, 2, 3]); + + const fromExistUser = new User(); + const fromExistTransformedUser = plainToClassFromExist(fromExistUser, fromPlainUser); + expect(fromExistTransformedUser).toBe(fromExistUser); + expect(fromExistTransformedUser.bytes).toBeInstanceOf(Uint8Array); + expect(Array.from(fromExistTransformedUser.bytes)).toEqual([1, 2, 3]); + }); + it('should transform nested objects too and make sure their decorators are used too', () => { defaultMetadataStorage.clear();