Skip to content

It is possible to violate generic constraints when distributing union typesΒ #63708

Description

@aweebit

πŸ”Ž Search Terms

constraint, conditional, distributive, distributed, distribution

πŸ•— Version & Regression Information

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

⏯ Playground Link

https://www.typescriptlang.org/play/?#code/C4TwDgpgBAkgznArhAPAQQDRQEJQgD2AgDsATOKNAPigF5K9CTypFiBrYgewHdiAoKFAD8ORkTIU2nXgKFDRAZQAWvdFmxVB8gFxRiEAG4QATtr0HjJgNz9+oSFBVrMYghJbU6UANqvsALpQAGRQAN4Avrb24NAAGt7wSKgADFAAPlAAjFhpmVlUtkA

πŸ’» Code

type Issue<A, B extends A> = A extends unknown
  ? B extends unknown
    ? Show<A, B>
    : never
  : never;

type Show<A, B extends A> = [A, B] & {};

type X = Issue<0 | 1, 0 | 1>;

πŸ™ Actual behavior

X is evaluated to [0, 0] | [0, 1] | [1, 0] | [1, 1].

No errors are reported despite the [0, 1] | [1, 0] part resulting from the evaluation of Show<0, 1> and Show<1, 0> which should not be allowed because of the B extends A constraint.

πŸ™‚ Expected behavior

An error is reported on line 3, saying the constraint might be violated.

Additional information about the issue

This is how the type should actually be implemented:

type Issue<A, B extends A> = A extends unknown
  ? B extends A
    ? Show<A, B> // only B members that extend the current A member reach this line
    : never
  : never;

Metadata

Metadata

Assignees

Labels

Needs InvestigationThis issue needs a team member to investigate its status.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions