0

I'm trying to desctructure an object into another object, I mean taking sub-set of properties from Object A to Object B. I'm doing it like this:

  const User = new UserImpl();
        User.email = user.email;
        User.name = user.name;
        User.family_name = user.familyName;
        User.password = 'Test!';
        User.verify_email = true;
        User.email_verified = false;
        User.blocked = false;
  const {
            email,
            name,
            family_name,
            password,
            verify_email,
            email_verified,
            blocked,
            connection
        } = User;
  const res_user = {
            email,
            name,
            family_name,
            password,
            verify_email,
            email_verified,
            blocked,
            connection
        };
        return res_user;

but, is there a way to do it using Object.assign() ? or using arrow => function instead of having two variables or doing it in two steps?

Thanks

basel.ai
  • 157
  • 2
  • 15
  • You might be able to use `Object.assign()` or object literal spread, but this code isn't really a [mcve] so it's hard to know what would meet your needs. If you're really only copying a subset of properties, can you make your example show this? It will be helpful if your code can be dropped into any IDE and show your issue. As it stands, you haven't defined `UserImpl` or `user`. – jcalz Jun 21 '19 at 15:40
  • `const objA = {...commonPart, foo: 'bar'}` and `const objB = {...commonPart, bim: 'bam'}`? – Phil Jun 21 '19 at 15:44

2 Answers2

2

If there are only a few properties that you want to copy, you could always get rid of the destructuring and just do:

  const res_user = {
    email: User.email,
    name: User.name,
    family_name: User.family_name,
    password: User.password,
    verify_email: User.verify_email,
    email_verified: User.email_verified,
    blocked: User.blocked,
    connection: User.connection,
  };
  return res_user;

This code is shorter than destructuring the User object just to restructure it later.

Alternatively, if there are only a few properties that you want to remove (and assuming you know there are no other properties) you could use a rest/spread parameter:

const {
   some_prop_i_dont_care_about,
   some_other_prop,
   ...res_user
} = User;
return res_user;

This will create a new object that contains every property except those explicitly listed above it, and assign that object to the variable res_user.

p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
  • This code didn't work, it takes all the properties because of using ...res_user part. const { some_prop_i_dont_care_about, some_other_prop, ...res_user } = User; return res_user; – basel.ai Jun 21 '19 at 15:52
  • 2
    @basel.ai "*This code didn't work*" Could be more specific? What's the error? If you're trying to cast `res_user` to a specific type, I'd have to know what's the actual type of `UserImpl` and the desired return type from this function. And like I said, the second solution will only work if there are no other unknown properties on `User`. If `UserImpl` is something like `{ [k: string]: any }` there's no way to ensure type safety of `res_user`. – p.s.w.g Jun 21 '19 at 15:57
2

If I were shallow-copying a list of properties I'd probably define a pick() function using the Pick type:

const pick = <T, K extends keyof T>(obj: T, ...keys: K[]) =>
  keys.reduce((acc, k) => ((acc[k] = obj[k]), acc), {} as Pick<T, K>);

And then assuming you have the following interface and object

interface User {
  email: string;
  name: string;
  familyName: string;
  password: string;
  verifyEmail: boolean;
  emailVerfified: boolean;
  blocked: boolean;
}

const u: User = {
  email: "luser@example.com",
  name: "Larry",
  familyName: "User",
  password: "th3b1gg3stLUSER",
  verifyEmail: true,
  emailVerfified: false,
  blocked: false
};

console.log(u); // everything

You could copy just the properties you care about to a new object like this:

const v = pick(u, "name", "familyName", "email");
// const v: Pick<User, "name" | "familyName" | "email">
// const v: {name: string, familyName: string, email: string}

console.log(v); // just name, familyName, email
// {name: "Larry", familyName: "User", email: "luser@example.com"}

Hope that helps; good luck!

Link to code

jcalz
  • 264,269
  • 27
  • 359
  • 360