2

I am trying to create a function in typescript to override the default values of an object with the values given in another object.

Basically it should take in 2 objects and add the non-null properties of 2nd object to the first object and return the modified obj. I could use destructuring like this {...a, ...b} but then if there are any null values in the b object, those would override the values in a object.

Here is a function I wrote, unfortunately, can't understand what typescript is complaining about.

function assignIfPresent<T extends Record<string, unknown>>(origObj: T, additions:Partial<T> ) {
    for (const propName in additions) {
        if (additions[propName])
            origObj[propName] = additions[propName];
    }

    return origObj;
}

error at origObj[propName]

const propName: Extract<keyof T, string>
Type 'T[Extract<keyof T, string>] | undefined' is not assignable to type 'T[Extract<keyof T, string>]'.
  Type 'undefined' is not assignable to type 'T[Extract<keyof T, string>]'.

UseCase:

class User {
    public firstName!: string;
    public lastName!: string;
    public gender?: string;
}

const newUser = new User();

newUser.lastName = "Biden"

const userDetails: Partial<User> = {
    firstName: "Joe",
    lastName: undefined,
}

console.log(assignIfPresent(newUser, userDetails)) //[LOG]: { "lastName": "Biden", "firstName": "Joe" } 
console.log({...newUser, ...userDetails}) //[LOG]: { "firstName": "Joe" } 

would be great if anyone can help me out.

1 Answer 1

1

I suggest du use lodash's pickBy to remove falsy values

import { pickBy } from 'lodash';

class User {
    public firstName!: string;
    public lastName!: string;
    public gender?: string;
}

const newUser = new User();

newUser.lastName = "Biden"

const userDetails: Partial<User> = {
    firstName: "Joe",
    lastName: undefined,
}

console.log({...newUser, ...pickBy(userDetails, _ => !!_)})

See stackblitz: https://stackblitz.com/edit/typescript-vthhuy?file=index.ts

Sign up to request clarification or add additional context in comments.

3 Comments

This solution works. I checked it out on stackbiltz. Thank you so much. I would love to know what is the cause of the error too. Would be great if you can help me understand it.
Because the loop also includes undefined. for(const propName in { lastName: 'foo' }) console.log(propName) prints lastNameand undefined, for(const propName in { }) console.log(propName) prints just undeifned.
I tried executing for (const propName in {lastName:"bkjsdb"}) console.log((propName === undefined || propName === null) ? "undefined1" : propName);. I was not able to get undefined to be printed on the console. Am i missing something here? please correct me if i am wrong.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.