Skip to content

MergeDeep loses subentries in case of optional object entries #1208

@jclaveau

Description

@jclaveau

Bug description

When merging deeply nested optional objects, sub-entries are lost

type OptionalNestedTest = {
	Left: {
		nested?: {
			in_left: string;
			sub_nested?: {
				number?: number;
			};
		};
	};
	Right: {
		nested: {
			in_right: string;
			sub_nested: {
				number: number;
			};
		};
	};
};

/*
Merge Right into Left: sub entries are lost
*/
type OptionalNestedRightIntoLeft = MergeDeep<
	OptionalNestedTest['Left'],
	OptionalNestedTest['Right']
>;

/**
it produces:

type OptionalNestedRightIntoLeft = {
    nested: {
        in_right: string;
        sub_nested: {
            number: number;
        };
    };
}

instead of:
type OptionalNestedRightIntoLeft = {
	nested: {
		in_left: string;   // currently missing
		in_right: string;
		sub_nested: {
			number: number;
		};
	};
};
 */


/*
Merge Left into Right: it adds som redundant "| undefined" (This may not be a bug)
*/
type OptionalNestedLeftIntoRight = MergeDeep<
	OptionalNestedTest['Right'],
	OptionalNestedTest['Left']
>;

/*
produces:

type OptionalNestedLeftIntoRight = {
    nested?: {
        in_right: string;
        in_left: string;
        sub_nested?: {
            number?: number | undefined;
        } | undefined;
    } | undefined;
}

instead of:
type OptionalNestedRightIntoLeft = {
    nested?: {
        in_right: string;
        in_left: string;
        sub_nested?: {
            number?: number;
        };
    };
};
 */

Repro

https://www.typescriptlang.org/play/?#code/JYWwDg9gTgLgBAbwFBzjAnmApnAslqAcywBEsswAaJAXzgDMoIQ4ByDbAWnqwGcZWSJBxwB5MDGAQAdgEMANgDk+MLABMAKirgBeREgCQAGSz0YALn0GD0leoD8l5NYPBpAfXmmLcflDeEANyG1rwArgBG7rb8Dk4h1tJhIBEEjnBJKQTBLjQ5BnmGhQYASsCEABY+zjZ2avEubu7+lT5+AfkG4VExqvVWLpmpUJZD2QnFBTmFhUgA9ABUSPhEOGWtcG4wEHAmZpbdcFjSMP58cLJQOPIQ-EgLc8KYYhJSckp161UAkicQe-A9CtiGQKAAeQziSQyBTKWKaFQAbVYANYAF1qAYoW9YXUtPxkV8BGikAA+YLzBZLYDwMBMNRhADGfHMQhEcGxMI+8KJv22AN0+lQqF66niwolmw8LSqB1OHRQktQ3WidXFSslYxGGWSw2CGrghQlMyEblisjUcAg9FZ7M57zhfV5fwFemcov6NSaXn2vnl0iCwrmczgjLCUCuJ3k6DgIGAvF4ARCTRlbX9QRCKo9DUSuoIozzUHyxRm+oeQkpywIxF23il2zgRMsNIuajUvF8zDgVwZ0jUshOcAARAAfOBhPumNzqIdwAAUGgq8djshj0gg8FSFzgETChAAlPdHnbXlzHeoAXyIETBcDSOQwBCsaeHXikawiejMfbcfD8TBkVRElySERYkDpCAGWZXhWSebAORfX8+kvP4bzdRURTqdJkANFNyllP1-ADfUNW9bw5SIjMDSzLD1QNEVC3SLU4DHCc1CnWw1BIpU6FYyd6GnLiMMNFjx34wTghoU1pHNS1rVtZ4EOhV8eXwmAr1dIVhQ9bDhIlPDWgohVcI8H000o7jJRo+FdPo7TGILLIiz04UjVcySy0eIA

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions