{"action":"opened","issue":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/23984","repository_url":"https://api.github.com/repos/Microsoft/TypeScript","labels_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/23984/labels{/name}","comments_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/23984/comments","events_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/23984/events","html_url":"https://github.com/Microsoft/TypeScript/issues/23984","id":321365847,"number":23984,"title":"`Exclude` for intersecting types","user":{"login":"rjamesnw","id":2531435,"avatar_url":"https://avatars0.githubusercontent.com/u/2531435?v=4","gravatar_id":"","url":"https://api.github.com/users/rjamesnw","html_url":"https://github.com/rjamesnw","followers_url":"https://api.github.com/users/rjamesnw/followers","following_url":"https://api.github.com/users/rjamesnw/following{/other_user}","gists_url":"https://api.github.com/users/rjamesnw/gists{/gist_id}","starred_url":"https://api.github.com/users/rjamesnw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rjamesnw/subscriptions","organizations_url":"https://api.github.com/users/rjamesnw/orgs","repos_url":"https://api.github.com/users/rjamesnw/repos","events_url":"https://api.github.com/users/rjamesnw/events{/privacy}","received_events_url":"https://api.github.com/users/rjamesnw/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-05-08T22:15:35Z","updated_at":"2018-05-08T22:15:35Z","closed_at":null,"author_association":"NONE","body":"## Search Terms\r\n\r\n`Exclude` for intersecting types.\r\n\r\n## Suggestion\r\n\r\nCurrently we have `Exclude<T, U>` and others - great job! I can finally clean up my code and work more efficiently. ;) That said, `Exclude` only works on union types.\r\n\r\n    type T02 = Exclude<string | number | (() => void), Function>;  // string | number\r\n\r\nThis does not work for intersection types:\r\n\r\n    type T02 = Exclude<string & number & (() => void), Function>;  // string & number\r\n\r\nI think some expected consistency would be nice,  In the code I was working on (factory types) I was returning the private class type AND an additional type that adds factory methods.  I do not want other classes to inherit this, so I need the original PRIVATE type (as in the type itself is not officially exported in the namespace [simply to not pollute the namespaces]).  Currently the workaround is to store the original type in a property and reference that later (see example).\r\n\r\n## Use Cases\r\n\r\nFor use with factory patterns.  I want to:\r\n1. Create namespaces with exposed factory types.\r\n2. Not pollute the namespaces with the private class types.\r\n3. Allow 3rd-parties to \"inherit\" from these factory types - which requires decomposing \r\n\r\n## Examples\r\n\r\nExample also here: https://stackoverflow.com/questions/50170849/how-can-i-decompose-intersecting-types-in-typescript\r\n\r\nFile1.ts - My system file.\r\n\r\n    namespace A {\r\n       class $PrivateTypeA { }\r\n       export var TypeA: typeof $PrivateTypeA & { create(a:string):any } = <any>$PrivateTypeA;\r\n    }\r\n\r\nFile2.ts - Some other developer using my file.\r\n\r\n    namespace B {\r\n       class $PrivateTypeB extends <Exclude<typeof A.TypeA, Func(a:any)=>any>><any>A.TypeA { } // (YES, I know this won't work, but it gives you the idea)\r\n       export var TypeB: typeof $PrivateTypeB & { create(a:number):any } = <any>$PrivateTypeB;\r\n    }\r\n\r\n## Checklist\r\n\r\nMy suggestion meets these guidelines:\r\n [x] This wouldn't be a breaking change in existing TypeScript / JavaScript code\r\n [x] This wouldn't change the runtime behavior of existing JavaScript code\r\n [x] This could be implemented without emitting different JS based on the types of the expressions\r\n [x] This isn't a runtime feature (e.g. new expression-level syntax)\r\n\r\n"}}
{"actor":{"display_login":"rjamesnw"}}