Skip to content

Combination of intersections/partials causes invalid nested object type to not report error #51043

Closed

Description

Bug Report

🔎 Search Terms

partial nested object type

🕗 Version & Regression Information

  • This changed between versions 4.5.5 and 4.6.4. It reproduces in all versions since 4.6.4 (including nightly)

⏯ Playground Link

Playground link with relevant code

💻 Code

type OverridesInput = {
    someProp?: 'A' | 'B'
}

const foo: Partial<{something: any}> & {variables: {
    overrides?: OverridesInput;
} & Partial<{
    overrides?: OverridesInput;
}>} = {variables: {overrides: false}};

🙁 Actual behavior

There is no error on the overrides field in the object. Changing the type of foo slightly (removing one of the intersections) causes the error to appear correctly, but this unique combination of types produces no error. Does not matter what the contents of OverridesInput is, nor what the content inside the outer partial (currently {something: any}) is. Additionally, the following all produce the error correctly:

type OverridesInput = {
    someProp?: 'A' | 'B'
}

const foo: {variables: {
    overrides?: OverridesInput;
} & Partial<{
    overrides?: OverridesInput;
}>} = {variables: {overrides: false}};
type OverridesInput = {
    someProp?: 'A' | 'B'
}

const foo: Partial<{something: any}> & {variables: {
    overrides?: OverridesInput;
}} = {variables: {overrides: false}};
type OverridesInput = {
    someProp?: 'A' | 'B'
}

const foo: Partial<{something: any}> & {variables: Partial<{
    overrides?: OverridesInput;
}>} = {variables: {overrides: false}};

🙂 Expected behavior

There should be an error on the overrides field of the object since false is not assignable to OverridesInput | undefined.

Activity

  1. RyanCavanaugh commented on Oct 4, 2022

    @RyanCavanaugh
    Member
    type OverridesInput = {
        someProp?: 'A' | 'B'
    }
    
    const foo: Partial<{something: any}> & {variables: {
        overrides?: OverridesInput;
    } & Partial<{
        overrides?: OverridesInput;
    // @ts-expect-error
    }>} = {variables: {overrides: false}};
  2. DanielRosenwasser commented on Oct 4, 2022

    @DanielRosenwasser
    Member

    This was a little easier for me to read.

    interface Unrelated { _?: any }
    
    // Identical but distinct types.
    interface VariablesA { overrides?: OverridesInput; }
    interface VariablesB { overrides?: OverridesInput; }
    
    const foo: Unrelated & { variables: VariablesA & VariablesB } = {
        variables: {
            // Should be an error here:
            overrides: false
        }
    };

    I would've expected some weak type checking on this one.

  3. typescript-bot commented on Oct 5, 2022

    @typescript-bot
    Contributor

    The change between release-4.4 and main occurred at 44e827b.

  4. RyanCavanaugh commented on Oct 5, 2022

    @RyanCavanaugh
    Member

    Anders Hejlsberg (@ahejlsberg) thoughts? This changed in #47738

  5. ahejlsberg commented on Oct 11, 2022

    @ahejlsberg
    Member

    The issue here is that when the target in a relation is an intersection, common property checks are only performed at the top level. For example:

    type A1 = { x: { a?: string } };
    type B1 = { x: { b?: string } };
    type C1 = { x: { c: string } };
    
    const ab1: A1 & B1 = {} as C1;  // No error
    
    type A2 = { a?: string };
    type B2 = { b?: string };
    type C2 = { c: string };
    
    const ab2: A2 & B2 = {} as C2;  // Error

    We definitely should error in both of the examples above.

  6. added
    BugA bug in TypeScript
    and removed
    Needs InvestigationThis issue needs a team member to investigate its status.
    on Oct 11, 2022
  7. locked as resolved and limited conversation to collaborators on Oct 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

BugA bug in TypeScriptFix AvailableA PR has been opened for this issue

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions