Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[type] multiple mixins & static methods #624

Open
ludorenzetti opened this issue Feb 7, 2025 · 2 comments
Open

[type] multiple mixins & static methods #624

ludorenzetti opened this issue Feb 7, 2025 · 2 comments

Comments

@ludorenzetti
Copy link

Hello again 👋

When testing mixins, I had three main issues identified. Maybe I'm not using them correctly?

Here is the reproduction of the following issues: codesandbox

  • Issue 1:

The static methods on mixins are present (visible via a console.log of static methods), but the mixin function doesn't seem to correctly infer the type for these static methods, since they are not present according to TypeScript inference.

  • Issue 2:

The order of mixins also seems to be problematic. In the provided reproduction, depending on whether the Serializable mixin is placed before or after Timestampable, the properties of one or the other are not copied. Example: put Serializable after Timestampable, the fromObject method no longer exists.

  • Issue 3:

Serialization of mixin properties doesn't seem to work. In the provided reproduction, if we put the Timestampable mixin first, the deserialization works fine, but the serialization does not include the properties of Timestampable.

Don't hesitate if you need more information or investigation! Tell me how I can help you 🙂

@marcj
Copy link
Member

marcj commented Feb 7, 2025

This code works for me:

    const date = new Date;

    class Timestampable {
        public readonly createdAt: Date = date;
        public updatedAt: Date = date;
    }

    class Serializable {
        public static fromObject<K extends new (..._args: any[]) => InstanceType<K>>(
            this: K,
            obj: unknown
        ): InstanceType<K> {
            return deserialize(obj, undefined, undefined, undefined, this);
        }

        public toObject() {
            return serialize(
                this,
                undefined,
                undefined,
                undefined,
                this.constructor as ReceiveType<this>
            );
        }
    }

    class Entity extends mixin(Serializable, Timestampable) {
        public readonly id: number = 0;
    }

    // @ts-ignore
    const entity = Entity.fromObject({ id: 1 });
    expect(entity).toBeInstanceOf(Entity);
    expect(entity).toEqual({ id: 1, createdAt: date, updatedAt: date });

    expect(entity.toObject()).toEqual({ id: 1, createdAt: date.toJSON(), updatedAt: date.toJSON() });

    const serialized = serialize<Entity>(entity);
    expect(serialized).toEqual({ id: 1, createdAt: date.toJSON(), updatedAt: date.toJSON() });

static functions are not mixed by mixin, so it's more or less luck that it works for you when you put it at first argument. I generally I recommend not to use statics on entities as this makes stuff rather complicated. Try to use normal functions instead, it's cleaner.

@ludorenzetti
Copy link
Author

Ok I understand better now. We were planning to remove these static methods anyway, we'll do that sooner than expected 😅 thanks for your feedback and work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants