tests/cases/compiler/excessPropertyCheckWithUnions.ts(10,30): error TS2322: Type '{ tag: "T"; a1: string; }' is not assignable to type 'ADT'.
  Object literal may only specify known properties, and 'a1' does not exist in type '{ tag: "T"; }'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(11,21): error TS2322: Type '{ tag: "A"; d20: number; }' is not assignable to type 'ADT'.
  Object literal may only specify known properties, and 'd20' does not exist in type '{ tag: "A"; a1: string; }'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(12,1): error TS2322: Type '{ tag: "D"; }' is not assignable to type 'ADT'.
  Property 'd20' is missing in type '{ tag: "D"; }' but required in type '{ tag: "D"; d20: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20; }'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(33,28): error TS2322: Type '{ tag: "A"; x: string; extra: number; }' is not assignable to type 'Ambiguous'.
  Object literal may only specify known properties, and 'extra' does not exist in type '{ tag: "A"; x: string; } | { tag: "A"; y: number; }'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(34,26): error TS2322: Type '{ tag: "A"; y: number; extra: number; }' is not assignable to type 'Ambiguous'.
  Object literal may only specify known properties, and 'extra' does not exist in type '{ tag: "A"; x: string; } | { tag: "A"; y: number; }'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(37,1): error TS2322: Type '{ tag: "A"; }' is not assignable to type 'Ambiguous'.
  Type '{ tag: "A"; }' is not assignable to type '{ tag: "A"; x: string; } | { tag: "A"; y: number; }'.
    Property 'y' is missing in type '{ tag: "A"; }' but required in type '{ tag: "A"; y: number; }'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(38,19): error TS2322: Type '{ tag: "A"; z: boolean; }' is not assignable to type 'Ambiguous'.
  Object literal may only specify known properties, and 'z' does not exist in type '{ tag: "A"; x: string; } | { tag: "A"; y: number; }'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(47,35): error TS2322: Type '{ a: 1; b: 1; first: string; second: string; }' is not assignable to type 'Overlapping'.
  Object literal may only specify known properties, and 'second' does not exist in type '{ a: 1; b: 1; first: string; }'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(48,35): error TS2322: Type '{ a: 1; b: 1; first: string; third: string; }' is not assignable to type 'Overlapping'.
  Object literal may only specify known properties, and 'third' does not exist in type '{ a: 1; b: 1; first: string; }'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(64,9): error TS2322: Type '{ kind: "A"; n: { a: string; b: string; }; }' is not assignable to type 'AB'.
  Types of property 'n' are incompatible.
    Type '{ a: string; b: string; }' is not assignable to type 'AN'.
      Object literal may only specify known properties, and 'b' does not exist in type 'AN'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(85,5): error TS2322: Type '{ tag: "button"; type: "submit"; href: string; }' is not assignable to type 'Union'.
  Object literal may only specify known properties, and 'href' does not exist in type 'Button'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(106,5): error TS2322: Type 'string' is not assignable to type 'IValue'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(111,67): error TS2322: Type 'string' is not assignable to type 'number'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(112,63): error TS2322: Type 'string' is not assignable to type 'number'.


==== tests/cases/compiler/excessPropertyCheckWithUnions.ts (14 errors) ====
    type ADT = {
        tag: "A",
        a1: string
    } | {
        tag: "D",
        d20: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20
    } | {
        tag: "T",
    }
    let wrong: ADT = { tag: "T", a1: "extra" }
                                 ~~
!!! error TS2322: Type '{ tag: "T"; a1: string; }' is not assignable to type 'ADT'.
!!! error TS2322:   Object literal may only specify known properties, and 'a1' does not exist in type '{ tag: "T"; }'.
    wrong = { tag: "A", d20: 12 }
                        ~~~
!!! error TS2322: Type '{ tag: "A"; d20: number; }' is not assignable to type 'ADT'.
!!! error TS2322:   Object literal may only specify known properties, and 'd20' does not exist in type '{ tag: "A"; a1: string; }'.
    wrong = { tag: "D" }
    ~~~~~
!!! error TS2322: Type '{ tag: "D"; }' is not assignable to type 'ADT'.
!!! error TS2322:   Property 'd20' is missing in type '{ tag: "D"; }' but required in type '{ tag: "D"; d20: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20; }'.
!!! related TS2728 tests/cases/compiler/excessPropertyCheckWithUnions.ts:6:5: 'd20' is declared here.
    
    type Ambiguous = {
        tag: "A",
        x: string
    } | {
        tag: "A",
        y: number
    } | {
        tag: "B",
        z: boolean
    } | {
        tag: "C"
    }
    let amb: Ambiguous
    // no error for ambiguous tag, even when it could satisfy both constituents at once
    amb = { tag: "A", x: "hi" }
    amb = { tag: "A", y: 12 }
    amb = { tag: "A", x: "hi", y: 12 }
    
    // correctly error on excess property 'extra', even when ambiguous
    amb = { tag: "A", x: "hi", extra: 12 }
                               ~~~~~
!!! error TS2322: Type '{ tag: "A"; x: string; extra: number; }' is not assignable to type 'Ambiguous'.
!!! error TS2322:   Object literal may only specify known properties, and 'extra' does not exist in type '{ tag: "A"; x: string; } | { tag: "A"; y: number; }'.
    amb = { tag: "A", y: 12, extra: 12 }
                             ~~~~~
!!! error TS2322: Type '{ tag: "A"; y: number; extra: number; }' is not assignable to type 'Ambiguous'.
!!! error TS2322:   Object literal may only specify known properties, and 'extra' does not exist in type '{ tag: "A"; x: string; } | { tag: "A"; y: number; }'.
    
    // assignability errors still work
    amb = { tag: "A" }
    ~~~
!!! error TS2322: Type '{ tag: "A"; }' is not assignable to type 'Ambiguous'.
!!! error TS2322:   Type '{ tag: "A"; }' is not assignable to type '{ tag: "A"; x: string; } | { tag: "A"; y: number; }'.
!!! error TS2322:     Property 'y' is missing in type '{ tag: "A"; }' but required in type '{ tag: "A"; y: number; }'.
!!! related TS2728 tests/cases/compiler/excessPropertyCheckWithUnions.ts:19:5: 'y' is declared here.
    amb = { tag: "A", z: true }
                      ~
!!! error TS2322: Type '{ tag: "A"; z: boolean; }' is not assignable to type 'Ambiguous'.
!!! error TS2322:   Object literal may only specify known properties, and 'z' does not exist in type '{ tag: "A"; x: string; } | { tag: "A"; y: number; }'.
    
    type Overlapping =
        | { a: 1, b: 1, first: string }
        | { a: 2, second: string }
        | { b: 3, third: string }
    let over: Overlapping
    
    // these two are still errors despite their doubled up discriminants
    over = { a: 1, b: 1, first: "ok", second: "error" }
                                      ~~~~~~
!!! error TS2322: Type '{ a: 1; b: 1; first: string; second: string; }' is not assignable to type 'Overlapping'.
!!! error TS2322:   Object literal may only specify known properties, and 'second' does not exist in type '{ a: 1; b: 1; first: string; }'.
    over = { a: 1, b: 1, first: "ok", third: "error" }
                                      ~~~~~
!!! error TS2322: Type '{ a: 1; b: 1; first: string; third: string; }' is not assignable to type 'Overlapping'.
!!! error TS2322:   Object literal may only specify known properties, and 'third' does not exist in type '{ a: 1; b: 1; first: string; }'.
    
    // Freshness disappears after spreading a union
    declare let t0: { a: any, b: any } | { d: any, e: any }
    declare let t1: { a: any, b: any, c: any } | { c: any, d: any, e: any }
    let t2 = { ...t1 }
    t0 = t2
    
    // Nested excess property checks work with discriminated unions
    type AN = { a: string } | { c: string }
    type BN = { b: string }
    type AB = { kind: "A", n: AN } | { kind: "B", n: BN }
    const abab: AB = {
        kind: "A",
        n: {
            a: "a",
            b: "b", // excess -- kind: "A"
            ~
!!! error TS2322: Type '{ kind: "A"; n: { a: string; b: string; }; }' is not assignable to type 'AB'.
!!! error TS2322:   Types of property 'n' are incompatible.
!!! error TS2322:     Type '{ a: string; b: string; }' is not assignable to type 'AN'.
!!! error TS2322:       Object literal may only specify known properties, and 'b' does not exist in type 'AN'.
        }
    }
    const abac: AB = {
        kind: "A",
        n: {
            a: "a",
            c: "c", // ok -- kind: "A", an: { a: string } | { c: string }
        }
    }
    
    // Excess property checks must match all discriminable properties
    type Button = { tag: 'button'; type?: 'submit'; };
    type Anchor = { tag: 'a'; type?: string; href: string };
    
    type Union = Button | Anchor;
    const obj: Union = {
        tag: 'button',
        type: 'submit',
    
        // should have error here
        href: 'foo',
        ~~~~
!!! error TS2322: Type '{ tag: "button"; type: "submit"; href: string; }' is not assignable to type 'Union'.
!!! error TS2322:   Object literal may only specify known properties, and 'href' does not exist in type 'Button'.
    };
    
    // Repro from #34611
    
    interface IValue {
      value: string
    }
    
    interface StringKeys {
        [propertyName: string]: IValue;
    };
    
    interface NumberKeys {
        [propertyName: number]: IValue;
    }
    
    type ObjectDataSpecification = StringKeys | NumberKeys;
    
    
    const dataSpecification: ObjectDataSpecification = {  // Error
        foo: "asdfsadffsd"
        ~~~
!!! error TS2322: Type 'string' is not assignable to type 'IValue'.
    };
    
    // Repro from #34611
    
    const obj1: { [x: string]: number } | { [x: number]: number } = { a: 'abc' };  // Error
                                                                      ~
!!! error TS2322: Type 'string' is not assignable to type 'number'.
    const obj2: { [x: string]: number } | { a: number } = { a: 5, c: 'abc' };  // Error
                                                                  ~
!!! error TS2322: Type 'string' is not assignable to type 'number'.
    
    // Repro from #33732
    
    interface I1 {
        prop1: string;
    }
    
    interface I2 {
        prop2: string;
    }
    
    interface I3 extends Record<string, string> {
    
    }
    
    type Properties =
        | { [key: string]: never }
        | I1
        | I2
        | I3
        ;
    
    
    declare const prop1: string;
    declare const prop2: string | undefined;
    
    function F1(_arg: { props: Properties }) { }
    F1({
        props: {
            prop1,
            prop2,
        },
    });
    
    function F2(_props: Properties) { }
    F2({
        prop1,
        prop2,
    });
    