Skip to content

TS gets very confused when merging objects inside a generic functionΒ #57466

Closed as not planned
@denis-migdal

Description

@denis-migdal

πŸ”Ž Search Terms

none

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about _________

⏯ Playground Link

Playground Link

πŸ’» Code

function foo<Data extends Record<string, any>>(data: Data) {


    const BASE_DATA = {
        "DELETED": true
    };

    // any merging method...
    // https://stackoverflow.com/questions/49682569/typescript-merge-object-types
    type RET_TYPE = Omit<Data, "DELETED"> & typeof BASE_DATA;

    let result  = Object.assign({}, data, BASE_DATA);
    let result2 = Object.assign({}, BASE_DATA, data);
    let result3 = {} as RET_TYPE;

    type T1 = RET_TYPE["DELETED"]; // = RET_TYPE["DELETED"]...

    type T2 = typeof result.DELETED; // boolean....
    type T3 = typeof result2.DELETED; // boolean.... wrong...
    type T4 = typeof result3.DELETED; // boolean.... so you know it...
    type T5 = typeof result3["DELETED"]; // = {...}["DELETED"]

    type RET_TYPE2 = Omit< Record<string, any>, "DELETED"> & typeof BASE_DATA;
    type T6 = RET_TYPE2["DELETED"]; // boolean...

    let i3: T1 = true; // error
    let i1: T5 = true; // error
    let i2: T6 = true; // ok
}

πŸ™ Actual behavior

In this context, TS is somehow losing type informations when manipulating types with [""] (cf T1 and T5), when he knows the type as shown by T4. In other contexts, TS doesn't lose the type informations as shown by T6.

There is also an issue with Object.assign() where the returned type is wrong (cf T3, data can have a member called DELETED that will override BASE_DATA.DELETED in the Object.assign().)

πŸ™‚ Expected behavior

TS shouldn't lose type informations and shouldn't bully me like that.

T3 should be any, as data can have a member called DELETED that will override BASE_DATA.DELETED in the Object.assign().

Additional information about the issue

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    UnactionableThere isn't something we can do with this issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions