Union type doesn't match the description in the Handbook



Bug Report

πŸ”Ž Search Terms

union; widen; type

πŸ•— Version & Regression Information

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

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

The Handbook describes the union type:

A union type is a type formed from two or more other types, representing values that may be any one of those types.

This means if we define type T = A | B, then its value can be any of A's values, or any of B's values. It implicitly means that if a value is not of type A or B, it is not a valid T value.

However, the code below shows that the same value is considered not A and not B, but is A | B. This contradicts the Handbook. One of them needs to changed to match the other. To me, the Handbook seems to make more sense.

type A = { a: number };
type B = { b: number };

const a: A = { a: 0, b: 1 }; // Error, "b" not allowed
const b: B = { a: 0, b: 1 }; // Error, "a" not allowed
const ab: A | B = { a: 0, b: 1 }; // No error, although the value is not a valid A or B

πŸ™ Actual behavior

A value of A | B can be neither A nor B.

πŸ™‚ Expected behavior

A value of A | B should be either A or B.

2022-10-04 21:21:40

Add a Comment

Top 3 Comments

  cnshenj answered on 2022-10-05 01:40:08

The explanation makes sense. Although it is not clear from the error that it is "regular" error or "linter" error. A related question, I'm afraid there is probably already a duplicate but I can't find it:

type A = { a: number };
type B = { b: string };

function isA(value: A | B): value is A {
    return "a" in value;

function foo<T extends A | B, K extends keyof T>(value: T, key: K) {
    if (isA(value)) {
        value["a"] + 1; // OK, value["a"] is number
        value[key] + 1; // Error. What type should key be to make this line valid?
0 positive reactions.
  MartinJohns answered on 2022-10-04 22:20:55

Duplicate of #20863.

The expected behavior is the actual behavior. Your value is both A and B, so it's also A | B. Excess property checks are more of a linter feature, but are not involved in the types.

edit: again 30 seconds too late, what's going on?!

0 positive reactions.
  IllusionMH answered on 2022-10-04 22:20:41

{ a: 0, b: 1 } is valid A, you just get excess properties check for plain object, which won't work for unions.

Looks like duplicate of #20863

Or you'll need exact types #12936 to make { a: 0, b: 1 } invalid A.

0 positive reactions.

Quick Hint

Does Microsoft Access and Oracle database support SQL?

SQL Developer fully support connections to Oracle 10g and above. Users can create Database Connections for non-Oracle databases MySQL, Microsoft SQL Server, Microsoft Access, Sybase, Teradata and IBM DB2 for object and data browsing. Limited worksheet capabilities also available for these databases.

Repo Information

Age 8yrs
Vendor microsoft
Repo Name TypeScript
Primary Language TypeScript
Default Branch main
Last Update 10 hours ago

Microsoft's Code Library

Similar Issues

πŸ’Ύ DirectXShaderCompiler Update Linux build and test workflows to use lit πŸ’¬ 3 open πŸ—“οΈ 17 hours ago
πŸ’Ύ DirectXShaderCompiler DXC API fails to report compilation error πŸ’¬ 3 closed πŸ—“οΈ 1 day ago
πŸ’Ύ vue-styleguidist fix(deps): update typescript-eslint monorepo to v5.45.0 πŸ’¬ 5 closed πŸ—“οΈ 1 day ago
πŸ’Ύ DirectXShaderCompiler [NFC] Address some low hanging fruit UBSan failures πŸ’¬ 5 open πŸ—“οΈ 1 day ago
πŸ’Ύ hash Update TypeScript to 4.9 πŸ’¬ 4 closed πŸ—“οΈ 2 days ago
πŸ’Ύ AzureTRE Amend conda configuration in Nexus πŸ’¬ 3 open πŸ—“οΈ 2 days ago
πŸ’Ύ AzureTRE Firewall policies and Ip group πŸ’¬ 3 open πŸ—“οΈ 2 days ago