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

Unexpected intersection type constraint error related to union, generic type and private field #38236

Closed
vilicvane opened this issue Apr 29, 2020 · 2 comments · Fixed by #38277
Assignees
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue

Comments

@vilicvane
Copy link

vilicvane commented Apr 29, 2020

TypeScript Version: 3.9.1-rc/4.0.0-dev.20200428

3.9.0-beta seems to be fine.

Search Terms: intersection,private,generic,constraint,union

Code

type Type = {foo: string} | {bar: number};

class SyncableObject {
  private foo: unknown;
}

interface SyncableRef<T extends ISyncableObject> {
}

interface ISyncableObject<T = object> extends SyncableObject {
}

type __ValueDescriptorType<
  T extends Type | undefined
> = T extends ISyncableObject
  ? SyncableRef<T>
  : T;

Expected behavior: No error

Actual behavior:

Type 'ISyncableObject<object> & T' does not satisfy the constraint 'ISyncableObject<object>'.
  Property 'foo' is missing in type 'ISyncableObject<object> & T' but required in type 'ISyncableObject<object>'.(2344)

Playground Link: Playground

Related Issues:

@DanielRosenwasser
Copy link
Member

I'm guessing related to #37762.

@DanielRosenwasser DanielRosenwasser added the Bug A bug in TypeScript label Apr 29, 2020
@DanielRosenwasser DanielRosenwasser added this to the TypeScript 3.9.2 milestone Apr 29, 2020
@vilicvane vilicvane changed the title Unexpected intersection type constraint error related to primitive union, generic type and private field Unexpected intersection type constraint error related to union, generic type and private field Apr 30, 2020
@ahejlsberg
Copy link
Member

ahejlsberg commented Apr 30, 2020

Actually, looks to be caused by #37537. We currently say that unions of object types never contain private or protected members. But that isn't quite right. A union of object types should contain any private or protected member that is present in every constituent and originates in exactly the same declaration. This rarely matters, but in this particular case we end up structurally relating the union ISyncableObject & object | ISyncableObject & string to ISyncableObject, and that fails (but shouldn't) because of the private member.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants