Skip to content

Class.assign() to return an typed Object.assign() #11508

Closed
@michaeljota

Description

@michaeljota

Scenario:

Right now Object.assign() doesn't return a typed Object. And as I see it, it should not return one. The Object.assign() should be use as in plain JS, allowing to shallow merge any typed objects.
Instead, I would suggest the use of a .assign(). This assign() should be a method in the Class object, and not in the instance. This would allow to explicit request and be sure you will only retrieve a typed object with the wanted class, in a way that I find easy to remember and logical to reproduce.

Syntactic:

   public static assign(...objs) {
        objs = objs.filter(obj => obj !== {} || obj === null || obj === undefined);
        return objs
            .map(obj => {
// I guess there is a better way to instance an object that assuming and empty constructor.
                let newObj = new T();
                Object.keys(newObj).forEach(key => {
                    if (obj.hasOwnProperty(key)) {
                        newObj[key] = obj[key];
                    };
                });
                return newObj;
            })
            .reduce((previus, current) => {
                return Object.assign(previus, current);
            });
    }

Emit:

This emit something like this (got it from the playground):

   T.assign = function () {
        var objs = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            objs[_i - 0] = arguments[_i];
        }
        objs = objs.filter(function (obj) { return obj !== {} || obj === null || obj === undefined; });
        return objs
            .map(function (obj) {
                var newObj = new T();
                Object.keys(newObj).forEach(function (key) {
                    if (obj.hasOwnProperty(key)) {
                        newObj[key] = obj[key];
                    }
                });
                return newObj;
        })
        .reduce(function (previus, current) {
            return Object.assign(previus, current);
        });
    };

Compatibility:

I just test this in the playground, but this is just plain JS to get a typed object.

Other:

  • Example code: (used to test it in the Playground)
class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
    public static assign(...objs) {
        objs = objs.filter(obj => obj !== {} || obj === null || obj === undefined);
        return objs
            .map(obj => {
                let newObj = new Greeter('');
                Object.keys(newObj).forEach(key => {
                    if (obj.hasOwnProperty(key)) {
                        newObj[key] = obj[key];
                    }
                });
                return newObj;
            })
            .reduce((previus, current) => {
                return Object.assign(previus, current);
            });
    }
}

let greeter = new Greeter("world");
greeter = Greeter.assign(
    {},
    greeter,
    {
        greeting: 'from Venezuela'
    });

let button = document.createElement('button');
button.textContent = "Say Hello";
button.onclick = function() {
    alert(greeter.greet());
}

document.body.appendChild(button);

I don't see that this can have any performance issues. I search a little before post this, but I have to recognize, but search was not exhaustive. This can help this #11100, and I think this can help this as well #11150, cause the spread can call it's own Class.assign internally.

I really hope you like this. :). Thanks you for reading.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions