Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

extends operator with literal types #54050

Closed
DPOH-VAR opened this issue Apr 28, 2023 · 2 comments
Closed

extends operator with literal types #54050

DPOH-VAR opened this issue Apr 28, 2023 · 2 comments
Labels
Not a Defect This behavior is one of several equally-correct options

Comments

@DPOH-VAR
Copy link

Bug Report

πŸ”Ž Search Terms

πŸ•— Version & Regression Information

⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.1.0-beta#code/C4TwDgpgBAglC8UDeAPAXAZ2AJwJYDsBzAXygB9l18BXAWwCMJtSLU0oMQGB7AG2IBQA0JCgAhBJUw4CJclJoMmLKVHrc+EAIb5BUfQcNHjJ0wYD05qAD0ovXMCZbeUEdAAWTCMPDQAwpJsWHhEKmyKjMxCblAAGoHowbLyEcoCllAABvEQKI74ACYY4plq1MBQ+NwVcNzYUH5CPqKxAPpwiDl5EIXFcAD8UABEXflFsENQ7COV1VC5Y31DANzpVvrW-dG+ca0SnfPdveJQgzMLPeNik9PxVRUXx9erGRtbzdBtAQeP4wFno0uxT8N2Gdzmv2BKzWBk221EMFa8UQcEhcVOw1RR3GsVBQzg90Oizi0NeNneMTESMkEjR8TOtOxxVxU2GEkJdNJ63J8P81MQATpGKGgqZJNZItmDzFuJe3LhQA

πŸ’» Code

type A = {x:string} | {x:number} | {x: symbol}

type B = {x:string} | {x:number} | {x: boolean}
                                       // ^ literal type here
type C = {x:string} | {x:number}

type X = {x:string | number}
// `X extends B` but not A or C


type X_A = X extends A ? "X extends A" : "X not extends A";
//   ^? X not extends A

type X_B = X extends B ? "X extends B" : "X not extends B";
//   ^? X extends B

type X_C = X extends C ? "X extends C" : "X not extends C";
//   ^? X not extends C

the bug is reproduced with any literal type instead of boolean

πŸ™ Actual behavior

X not extends A
X extends B;
X not extends C

πŸ™‚ Expected behavior

X not extends A
X not extends B
X not extends C

@jcalz
Copy link
Contributor

jcalz commented Apr 29, 2023

#30779 implemented this behavior intentionally, and it is documented in the TS3.5 release notes. Unions with discriminant-worthy properties (involving literals) are related differently, on purpose. That results in:

type A = { x: string } | { x: number } | { x: symbol }
type B = { x: string } | { x: number } | { x: boolean }
type C = { x: string } | { x: number }

type X = { x: string | number }

const x: X = { x: Math.random() < 0.5 ? "abc" : 123};
const a: A = x; // error
const b: B = x; // okay
const c: C = x; // error

And so extends is behaving the way assignability behaves. Maybe it's inconsistent, but it's not a bug.

@RyanCavanaugh RyanCavanaugh added the Not a Defect This behavior is one of several equally-correct options label May 2, 2023
@github-actions
Copy link

github-actions bot commented Jun 8, 2023

This issue has been marked as 'Not a Defect' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Jun 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Not a Defect This behavior is one of several equally-correct options
Projects
None yet
Development

No branches or pull requests

3 participants