From cec130550d795b8737dd21eaa90e5266113e24e8 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 20 Sep 2024 15:33:03 +0200 Subject: [PATCH] opaque-internal: support class implementations Signed-off-by: Patrik Oldsberg --- .../opaque-internal/src/OpaqueType.test.ts | 36 +++++++++++++++++++ packages/opaque-internal/src/OpaqueType.ts | 5 ++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/packages/opaque-internal/src/OpaqueType.test.ts b/packages/opaque-internal/src/OpaqueType.test.ts index 2e49ca9029..94fcb18d36 100644 --- a/packages/opaque-internal/src/OpaqueType.test.ts +++ b/packages/opaque-internal/src/OpaqueType.test.ts @@ -413,4 +413,40 @@ describe('OpaqueType', () => { expect(myInternal.$$type).toBe('my-type'); expect(myInternal.version).toBe(undefined); }); + + it('should work with class implementations', () => { + type MyType = { + $$type: 'my-type'; + }; + + const OpaqueMyType = OpaqueType.create<{ + public: MyType; + versions: { + version: 'v1'; + getX(): number; + }; + }>({ + type: 'my-type', + versions: ['v1'], + }); + + class MyTypeImpl { + getX() { + return 4; + } + } + + const myInstance = OpaqueMyType.createInstance('v1', new MyTypeImpl()); + + expect(myInstance.$$type).toBe('my-type'); + + expect(OpaqueMyType.isType(myInstance)).toBe(true); + + const myInternal = OpaqueMyType.toInternal(myInstance); + expect(myInternal).toBe(myInstance); + + expect(myInternal.$$type).toBe('my-type'); + expect(myInternal.version).toBe('v1'); + expect(myInternal.getX()).toBe(4); + }); }); diff --git a/packages/opaque-internal/src/OpaqueType.ts b/packages/opaque-internal/src/OpaqueType.ts index 7b6b6e0767..dd17f21da8 100644 --- a/packages/opaque-internal/src/OpaqueType.ts +++ b/packages/opaque-internal/src/OpaqueType.ts @@ -135,11 +135,10 @@ export class OpaqueType< : never) & Object, // & Object to allow for object properties too, e.g. toString() ): TPublic { - return { - ...(props as object), + return Object.assign(props as object, { $$type: this.#type, ...(version && { version }), - } as unknown as TPublic; + }) as unknown as TPublic; } #isThisInternalType(value: unknown): value is T['public'] & T['versions'] {