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

Intersection Types that have overlapping properties can fail #49264

Closed
wdamien opened this issue May 26, 2022 · 4 comments
Closed

Intersection Types that have overlapping properties can fail #49264

wdamien opened this issue May 26, 2022 · 4 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@wdamien
Copy link

wdamien commented May 26, 2022

This seems to be the source: #31838

Example:
Try an intersection of 2 types where the same property has inconsistent overlapping types:

type Bar = {
    Prop: string
};

type Works = Bar & {Prop: number}; // Bar & {Prop: number}
type ThisIsNever = Bar & {Prop: null}; // never

It makes sense to me that individual types can be reduced to never, but why can intersecting types with nested overlapping property types get reduced to never?

Playground link: https://www.typescriptlang.org/play?ts=4.7.0-beta#code/C4TwDgpgBAQghgJygXigbwFBW1ACggezAC4oBnYBASwDsBzDAXwG4MMB6dqAdQIQGsyUAGa0IGUJCgBJGsAgIyEAMbAqBGiliIoAMnT4ipGgFcAtgCMFLKJ21J9aQySinL1ieGgA5CADcFWXlFFTUNLXgHA0IXGn9rZlsuSL1oo1d4hEY2O28CYCgIAA9IVQgAE08pbxMAG1qghSVVdU1UFMdnYzramzsAJRUIKgDy40ykqABREtCK0gADDrTYnsYFqAAKPiglnU6Y8YCshYBKKugAVRpyiFE48saQlvD2-ZXSExu7sXK+rkGymGoyOCkmM1K8jGu2WTkOUC+t3uFXWWx2eyicPScWO63OQA

This might be expected, but it does feel like a bug to me. My initial use case was joining a few different types together to get a union of all their keys. But since some props had a null | undefined type, it was reduced to never. Causing my use of those keys to fail unexpectedly. I would expect ThisIsNever to have a Prop: never property instead, or maybe a union of string | null. Or at-least surface an error saying the union is not possible because of Prop being incompatible.

Tested on: 4.6.4, 4.7.0-beta
This worked as expected in: v3.8.3. And starts not being expected in v3.9.7

@jcalz
Copy link
Contributor

jcalz commented May 26, 2022

You didn't fill out the template.

This is working as intended as per #36696. Since TypeScript 3.9, intersections are reduced by discriminant properties. null and undefined are unit/singleton types, and a property whose member types contain at least one unit/singleton type are considered discriminant properties.

@andrewbranch andrewbranch added the Working as Intended The behavior described is the intended behavior; this is not a bug label May 26, 2022
@fatcerberus
Copy link

Shouldn’t both types reduce to never? Realistically it’s not possible to produce a value of either one.

@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented May 26, 2022

Conflicting primitives are in the grey zone between conflicting unit types and conflicting object types. It's definitely not possible to produce an intersection of two unit types, definitely is possible to produce an intersection of two object types (or at least it's not computable to determine if any two arbitrary object types have zero overlap), but intersections between two primitives sometimes arise in places that are benign.

@typescript-bot
Copy link
Collaborator

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

6 participants