Skip to content

Type union not matched starting from TS 5.1Β #58603

Closed
@WGroenestein

Description

@WGroenestein

πŸ”Ž Search Terms

"5.1", "type union"

πŸ•— Version & Regression Information

  • This changed between versions 5.0 and 5.1 (based on playground version selection)

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.5.0-beta#code/LAKApgdgrgtgBAWQJ4FFrwN6gJAEE4C8cAjADQ4BChcATKAL6igAuSADmHACrtj5FYQ2ANYBLCABMAXIlToAdLgDcOURID8M9ACMwAJxUh6hlr268qAnGMkzkaWPIqHGIAGRwAFDkHZsazTgoSTAAM3EwCUNsV2wAHx8cf2k4HX1o1wBKExBWDlkefKJCvjg48w5nJhBQ4IBjZlEAewg4AGUmmDBmAAtxAHNPAEM7JBLMmQA3JrU4DFdQDq7egc8MOBsU+wV8emzFzu6+iEH1zdGHGCc4PcMlo9Wz8S25R1xSODUZYIkwiIkbvsQPcVic1htnhcdh8viRAXdDqDThDbLJLk4YSkfn8IJF4Qdlsdkec0QoKJiZMR8SBQLUIA1mq0AJKSUR6MANTwk7awTGBNJ6CZwaazXwgolrJKbchCZI4W4Map0hktOAsiRsjnMGhcyGk3mfDRaWC6QVTGYA3wAZwA7qJmHUel5Npk5kk6kMrZweVdcFJ3Z7va8rhR-bLsOLHkk-NLo3Lwwrw9p2UNhNFsL9QkMoAAbZhhvzYZNgVMZRU0mr1Rqq9WahoAZl1qJ9fONMFNQpFlpwtvtjudz1dvmwHq9+t9Bb8kbBw5jzxlhfjhcTheLpeqflHQfRoej09Ocdj4aXfhXfjXaaSmezecnRZTl6ErnoQA

πŸ’» Code

enum MyEnum {
	A = 1,
	B = 2
}

type TypeA = {
	kind: MyEnum.A;
	id?: number;
};

type TypeB = {
	kind: MyEnum.B;
}
& (
	{
		id?: undefined;
	}
	|
	{
		id: number;
	}
);

type MyType = TypeA | TypeB;

function Something(a: MyType): void {}

Something({ kind: MyEnum.A });
Something({ kind: MyEnum.B });
Something({ kind: MyEnum.A, id: undefined });
Something({ kind: MyEnum.A, id: 1 });
Something({ kind: MyEnum.B, id: undefined });
Something({ kind: MyEnum.B, id: 1 });

function Indirect(kind: MyEnum, id?: number): void {
	Something({
		kind,
		id
	});
}

function Indirect2(kind: MyEnum, id?: number): void {
	switch (kind) {
		case MyEnum.A:
		case MyEnum.B:
			Something({
				kind,
				id
			});
			break;
		default:
			break;
	}
}

function Indirect3(kind: MyEnum, id?: number): void {
	switch (kind) {
		case MyEnum.A:
			Something({
				kind,
				id
			});
			break;

		case MyEnum.B:
			Something({
				kind,
				id
			});
			break;
		default:
			break;
	}
}

πŸ™ Actual behavior

Indirect and Indirect2 report an error, while Indirect3 does not even though the call signature is identical (there is just an extra type check)

Argument of type '{ kind: MyEnum; id: number | undefined; }' is not assignable to parameter of type 'MyType'.
  Types of property 'kind' are incompatible.
    Type 'MyEnum' is not assignable to type 'MyEnum.A'.(2345)

πŸ™‚ Expected behavior

All 3 versions of Indirect behave the same and produce no errors

Additional information about the issue

We are currently on 4.9 and are preparing to migrate to 5.5 once it goes GA.
In our codebase TypeB has some additional required fields when id is a numer, hence the union.

I did observe that a simpler call signature (using only the discriminator) also fails in 4.9 and 5.0

Something({ kind });

Metadata

Metadata

Assignees

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