TypeScript icon indicating copy to clipboard operation
TypeScript copied to clipboard

C extends A but C does not extend A | B

Open jer-sen opened this issue 1 year ago • 3 comments

🔎 Search Terms

union extends

🕗 Version & Regression Information

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

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.5.2#code/C4TwDgpgBAglC8UDeUCGAuKBGANFARpgM7ABOAlgHYDmAvlAD7JqYBMUehUJFNtA3AFgAUKEhQAQgmYYorPAGNiZKtSgCRY6AGFpKWVkZzOy3mo3DN4aAHUA9qQDWRADwAVKBAAewCJQAmRLDS2gB80m5CotZQACJ2EEQAcnbA9k7unj5+gcFMUohhEfxAA

💻 Code

type A = { a: 1, b: string} | { a: 2 , b: string};
type B = { a: 2, c: string };
type C = { a: 1 | 2, b: string };

type Works<T extends A = C> = T;
type DoesNotWork<T extends A | B = C> = T;

🙁 Actual behavior

An error tells that C does not extend A | B

🙂 Expected behavior

No error since C extends A and therefore extends A | B

Additional information about the issue

No response

jer-sen avatar Jun 26 '24 08:06 jer-sen

This is a fallout of an extra attempt to match combinations in typeRelatedToDiscriminatedType. The normal union-based match fails here in both cases and it's just that fallback match that even allows Works to work.

I'd probably call it a design limitation as that fallback match is something that, IIRC, breaks some general rules. { prop: A } | { prop: B } isn't always interchangeable with { prop: A | B }. This fallback match also only works to a certain number of combinations so it's already not something that works universally.

Andarist avatar Jun 26 '24 09:06 Andarist

Maybe the fallback match could be improved a bit. The repro is very simple and should be handle correctly IMHO.

jer-sen avatar Jun 26 '24 17:06 jer-sen

Possibly related? https://github.com/microsoft/TypeScript/issues/36969

ethanresnick avatar Jun 29 '24 21:06 ethanresnick