2

Is there a way to clone an object with specified keys. For example you have this object

const User = {
  firstName: '',
  lastName: '',
  age: '',
  gender: '',
  job: '',
}

and you just want to clone or extract the firstName and lastName to create another object like:

const UserPublicInfo = {
  firstName,
  lastName,
}

I know a few solutions but...

Solution #1: Manual

const UserPublicInfo = {
  firstName: User.firstName,
  lastName: User.lastName,
}

Caveat

There is no problem with a small list but this is going to be tedious with a large list, let's say 10+ keys or more.

Solution #2: Rest Operator

We can omit the keys specifically with Rest Operator

const { firstName, lastName, ...UserPublicInfo } = User

Caveat

This is easier than the first solution but the problem is what if you don't know the properties of the User object? Yes you can console.log the content but what if later in your development a team mate has updated this User object and decided to add another property, your app will mostly like cause errors along the way. So security-wise Solution #1 is better.

I was hoping it could be done easy like in the following code but it throws error on my transpiler.

const UserPublicInfo = { firstName, lastName } = User

Are there better solutions out there for this use-case?

JohnnyQ
  • 4,839
  • 6
  • 47
  • 65
  • 3
    This question has been asked many times. The term usually used for this operation is "picking", so you could search for that. The basic answer is no, there is no easy, direct way. You could check out http://stackoverflow.com/questions/25553910/one-liner-to-take-some-properties-from-object-in-es-6/25835337#25835337. –  Apr 18 '17 at 12:22
  • method 2 doesn't look valid (babel doesn't like it at all) – Jaromanda X Apr 18 '17 at 12:33
  • 2
    BTW this is not the "rest operator"; the correct term is "object rest properties". See https://github.com/tc39/proposal-object-rest-spread. –  Apr 18 '17 at 13:20
  • [`...` is not an operator!](http://stackoverflow.com/a/37152508/218196) – Felix Kling Apr 18 '17 at 16:55
  • Probably the most concise way to pick keys out of an object explicitly is to do it with an array. – Jason Mitchell Nov 26 '19 at 22:28
  • Probably the most concise way to pick keys explicitly from an object with a long list is to do it with an Array. function picked(obj,array) { var retr={}; array.every(k=>retr[k]=obj[k]); return retr; } I know there is a way to use reduce to make that a one liner. But having your client code be simple should be enough. You don't have to use ES6 for every problem that's already been solved. – Jason Mitchell Nov 26 '19 at 22:32

1 Answers1

1

You can see this implementation (but ES6 capability) of cloning, the idea of Object.Assign() and deep-cloning by Function.prototype.apply:

export class ClonerAssign<T> implements interfaces.ICloner{
        clone<T>(sample: T): T {
            var proto = Object.getPrototypeOf(sample);
            //soft clone
            var _new = Object.assign({}, sample, proto, Object.getPrototypeOf(proto));

            //deep clone
            var _props = props(proto).filter(x => notCoreFunc(x));
            _props.forEach(key => {
                if (typeof proto[key] === 'function') {
                    (_new as any)[key] = (...args: any[]) => {
                        (proto[key] as any).apply(_new, args);
                    };
                }
            });

            return _new;
        }
    }