Skip to content

Unexpected error message when assigning object values with wider discriminator property typeΒ #62603

@janpaepke

Description

@janpaepke

πŸ”Ž Search Terms

discriminated unions, property incompatibility

πŸ•— Version & Regression Information

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

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=3.9.7#code/C4TwDgpgBAqgdgSwPZwCrmgXigIgGZJI5QA+uARgIYBOxZOVAXjgNwBQbokUAIggM4BjaggC2COJWAQAJlExsopKAG9FSjTIHCxEqUmoAuXASLsNUAL7qyai0q1CR4ycAPGGNVuqWX2HQRR+YCgIAA9IQWkZAFFqandebWc9aPlVKEcdF30jE0JiSn5YRBR0bms2QLhgqABXOHDI6LiEvL4nXVdZdJVM5K7cj1NiSygijKyU10T4ZDQMK3YgA

πŸ’» Code

type UnionType = "foo" | "bar" | "baz";

type Discriminated =
  | {
      discriminator: "foo";
    }
  | {
      discriminator: "bar";
    };


const expectedError: Discriminated = { discriminator: "foo" as UnionType }

const unexpectedError: Discriminated = { discriminator: "foo" } as { discriminator: UnionType };

πŸ™ Actual behavior

For unexpectedError, this is the compiler message:

Type '{ discriminator: UnionType; }' is not assignable to type 'Discriminated'.
  Type '{ discriminator: UnionType; }' is not assignable to type '{ discriminator: "bar"; }'.
    Types of property 'discriminator' are incompatible.
      Type 'UnionType' is not assignable to type '"bar"'.
        Type '"foo"' is not assignable to type '"bar"'.

This error is very misleading since "foo" is not actually the problem here, it's "baz".
In fact the error goes away, if we remove "baz" from the union.

πŸ™‚ Expected behavior

For expectedError the compiler states:

Type 'UnionType' is not assignable to type '"foo" | "bar"'.
  Type '"baz"' is not assignable to type '"foo" | "bar"'.

Consequently, the correct error message I would expect for unexpectedError is this:

Type '{ discriminator: UnionType; }' is not assignable to type 'Discriminated'.
  Type '{ discriminator: UnionType; }' is not assignable to type '{ discriminator: "foo" | "bar"; }'.
    Types of property 'discriminator' are incompatible.
      Type 'UnionType' is not assignable to type '"foo" | "bar"'.
        Type '"baz"' is not assignable to type '"foo" | "bar"'.

Additional information about the issue

This is a simplified example of this issue, which I discovered, when attempting to supply a parameter a function expecting a discriminated union.
The supplied variable had a wider range of possible discriminator values, like shown in this example.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Not a DefectThis behavior is one of several equally-correct options

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions