Skip to content

Regression - default initializer of {} ruins type intersected with object #49480

Closed

Description

export interface BarProps {
    barProp?: string;
}

export interface FooProps {
    fooProps?: BarProps & object;
}

declare const foo: FooProps;
const { fooProps = {} } = foo;

fooProps.barProp;
//       ~~~~~~~
// error! Property 'barProp' does not exist on type '{}'.

Activity

  1. DanielRosenwasser commented on Jun 10, 2022

    @DanielRosenwasser
    MemberAuthor

    TypeScript Bot (@typescript-bot) bisect good v4.7.3 bad main

  2. DanielRosenwasser commented on Jun 10, 2022

    @DanielRosenwasser
    MemberAuthor

    Forgot to add strictNullChecks, but it shouldn't matter.

  3. typescript-bot commented on Jun 10, 2022

    @typescript-bot
    Contributor

    The change between v4.7.3 and main occurred at 5aa0053.

  4. typescript-bot commented on Jun 10, 2022

    @typescript-bot
    Contributor

    👋 Hi, I'm the Repro bot. I can help narrow down and track compiler bugs across releases! This comment reflects the current state of the repro in the issue body running against the nightly TypeScript.


    Issue body code block by Daniel Rosenwasser (@DanielRosenwasser)

    ‼️ Exception: Error - Did not find a source file for /home/runner/work/TypeScript/TypeScript/index.ts

    Error: Did not find a source file for /home/runner/work/TypeScript/TypeScript/index.ts
        at Object.updateFile (/home/runner/work/_actions/microsoft/TypeScript-Twoslash-Repro-Action/master/dist/index.js:6876:15)
        at _loop3 (/home/runner/work/_actions/microsoft/TypeScript-Twoslash-Repro-Action/master/dist/index.js:1738:9)
        at twoslasher (/home/runner/work/_actions/microsoft/TypeScript-Twoslash-Repro-Action/master/dist/index.js:1744:17)
        at /home/runner/work/_actions/microsoft/TypeScript-Twoslash-Repro-Action/master/dist/index.js:777:44
        at runTwoslashRequests (/home/runner/work/_actions/microsoft/TypeScript-Twoslash-Repro-Action/master/dist/index.js:744:56)
        at run (/home/runner/work/_actions/microsoft/TypeScript-Twoslash-Repro-Action/master/dist/index.js:2169:75)
        at runMicrotasks (<anonymous>)
        at processTicksAndRejections (node:internal/process/task_queues:96:5)
    

    Historical Information
    Version Reproduction Outputs Time
    4.3.2, 4.4.2, 4.5.2, 4.6.2, 4.7.2

    👍 Compiled

    ⚠️ Way slower
  5. fatcerberus commented on Jun 10, 2022

    @fatcerberus

    The change between v4.7.3 and main occurred at 5aa0053.

    That’s the second time it’s done that…

  6. weswigham commented on Jun 10, 2022

    @weswigham
    Member

    methinks the twoslasher is broken with latest TS - the bug workbench does the same thing.

  7. DanielRosenwasser commented on Jun 10, 2022

    @DanielRosenwasser
    MemberAuthor

    First repros on typescript@4.8.0-dev.20220528

    Merge list on May 27th is https://github.com/microsoft/TypeScript/pulls?q=is%3Apr+merged%3A2022-05-27+is%3Aclosed

    Likely introduced by #49119

  8. ahejlsberg commented on Jun 12, 2022

    @ahejlsberg
    Member

    Yup, this is caused by #49119. It modified simpleTypeRelatedTo to consider {} a supertype of object in the strictSubtypeRelation. But really that should only be true for a non-fresh {}. In other words, we want fresh {} <: object <: {} in the strict subtype relation (i.e. fresh {} is a subtype of object which is a subtype of {}).

    Also, for some reason we remove object literal freshness from the source side when relating to an intersection on the target side. Lost in history as to why, removing it doesn't change any baselines.

    In combination, those two changes fix the issue. I will put up a PR.

  9. DanielRosenwasser commented on Jun 13, 2022

    @DanielRosenwasser
    MemberAuthor

    In other words, we want {} <: object <: fresh {} in the strict subtype relation.

    You mean the reverse, right?

    fresh {} ≤ object ≤ {}

  10. ahejlsberg commented on Jun 13, 2022

    @ahejlsberg
    Member

    Daniel Rosenwasser (@DanielRosenwasser) Argh, yes. I always read <: as is-supertype-of because it looks like an inheritance tree on its side. But you're right, it should be the other way around. I'll correct it.

  11. DanielRosenwasser commented on Jun 13, 2022

    @DanielRosenwasser
    MemberAuthor

    GitHub now lets you do Mermaid diagrams. This should make it easier to read 😄

    graph BT;
        emptyObject("{}");
        nonPrimitive("object");
        freshEmptyObject("fresh {}");
        freshEmptyObject --> nonPrimitive --> emptyObject;
    
    Loading
  12. fatcerberus commented on Jun 13, 2022

    @fatcerberus

    Mermaid diagrams

    I've never heard this term before.

    Also, on Anders Hejlsberg (@ahejlsberg)'s note, I've personally always felt like the arrows in inheritance diagrams go in the wrong direction (cause <- effect is weird), so I find fresh {} ≤ object ≤ {} to actually be easier to read.

  13. RyanCavanaugh commented on Jun 13, 2022

    @RyanCavanaugh
    Member

    It's super weird because I want class arrows to go one way but subtyping arrows to go the other way. Human brains are a mess.

  14. 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 issueHas ReproThis issue has compiler-backed repros: https://aka.ms/ts-repros

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions