0

Consider the following example:

const assign = <T, K extends keyof T>(...args: T[]): T =>
    args.reduce((result, current) =>
        (Object.keys(current) as K[]).reduce((target, key) => {
            target[key] = current[key];
            return target;
        }, result)
        , args[0]);

class Base {
    str1: string = '';
    str2: string = '';

    constructor(data: Partial<Base>) {
        assign(this, data);
    }
}

class Derived extends Base {
    str3: string = '';

    constructor(data: Partial<Derived>) {
        super(data);
        Object.assign(this, data);
    }
}

const derivedObj = new Derived({ str1: 'text', str3: 'new prop' })
const baseObject = new Base(derivedObj);

console.log(baseObject);
// Outputs:
// Data { "str1": "text", "str2": "", "str3": "new prop" } 

The base class comprises less properties than the derived class. The base class constructor accepts a Partial<Base> which is also compatible with the Partial<Derived> type. This results in extraneous properties being assigned to the base class object when passing an object of type Partial<Derived>.

Is there a way to initialize the base class object only with its class-specific properties (str and str2 and not str3)?

PS: There are a lot of seemingly similar discussions on GitHub and here. So far, I haven't found any which tackles this exact problem.

1 Answer 1

1

This works:

const assign = <T, K extends keyof T>(...args: T[]): T =>
    args.reduce((result, current) =>
        (Object.keys(args[0]) as K[]).reduce((target, key) => {
            if (current[key] !== undefined) target[key] = current[key];
            return target;
        }, result)
    , args[0]);

See this playground

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

1 Comment

Thank you, looking at your code, I realize I was so close. :)

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.