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

Correct the section about discriminated union types #183

Closed
wants to merge 1 commit into from
Closed

Conversation

denis-sokolov
Copy link
Contributor

The previous explanation was incorrect. An object can not be at the same time
{ value: "foo" } and { value: [number, number] }, the two are incompatible.

Instead, this is a design limitation of TypeScript compiler in that it does not narrow
the type of the parent object after narrowing a property.
microsoft/TypeScript#30506 (comment)

The previous explanation was incorrect. An object can not be at the same time
`{ value: "foo" }` and `{ value: [number, number] }`, the two are incompatible.

Instead, this is a design limitation of TypeScript compiler in that it does not narrow
the type of the parent object after narrowing a property.
microsoft/TypeScript#30506 (comment)
}
```

Even though we have narrowed based on `event.value`, the logic doesn't filter up and sideways to `event.target`. This is because a union type `UserTextEvent | UserMouseEvent` could be BOTH at once. So TypeScript needs a better hint. The solution is to use a literal type to tag each case of your union type:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the example should not be deleted. It's a good illustration. But you are correct, the language here does sound confusing.

You can move it below the actual example and collapse it.
You can change the explanation to "
Take care: TypeScript does not narrow the type of a Discriminated Union on the basis of typeof checks. The type guard has to be on the value of a key and not it's type.
microsoft/TypeScript#30506 (comment)
"

Copy link
Member

@eps1lon eps1lon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An object can not be at the same time
{ value: "foo" } and { value: [number, number] }, the two are incompatible.

Correct, "foo" & [number, number] would be evaluated to never make little sense. However, we use a union not an intersection so the type is "foo" | [number, number].

The example works in the typescript playground. Could you demonstrate with example code (+config and version) on the typescript playground that this example isn't working?

@denis-sokolov
Copy link
Contributor Author

@eps1lon, your response is unrelated to my PR description, I never talked about an intersection.

I have pointed out what I consider to be a wrong explanation in case you had missed it before. If you find it useful, feel free to improve your materials further. If you find them useless, I don’t mind, feel free to ignore.

@azizhk
Copy link
Collaborator

azizhk commented Mar 24, 2020

Thank you @denis-sokolov for this PR. Your work is merged in #205
Please do keep contributing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants