{"action":"created","issue":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/3622","labels_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/3622/labels{/name}","comments_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/3622/comments","events_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/3622/events","html_url":"https://github.com/Microsoft/TypeScript/pull/3622","id":90820417,"number":3622,"title":"Intersection types","user":{"login":"ahejlsberg","id":4226954,"avatar_url":"https://avatars.githubusercontent.com/u/4226954?v=3","gravatar_id":"","url":"https://api.github.com/users/ahejlsberg","html_url":"https://github.com/ahejlsberg","followers_url":"https://api.github.com/users/ahejlsberg/followers","following_url":"https://api.github.com/users/ahejlsberg/following{/other_user}","gists_url":"https://api.github.com/users/ahejlsberg/gists{/gist_id}","starred_url":"https://api.github.com/users/ahejlsberg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ahejlsberg/subscriptions","organizations_url":"https://api.github.com/users/ahejlsberg/orgs","repos_url":"https://api.github.com/users/ahejlsberg/repos","events_url":"https://api.github.com/users/ahejlsberg/events{/privacy}","received_events_url":"https://api.github.com/users/ahejlsberg/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/Microsoft/TypeScript/labels/cla-not-required","name":"cla-not-required","color":"009800"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":39,"created_at":"2015-06-25T01:14:38Z","updated_at":"2015-07-31T14:28:52Z","closed_at":"2015-07-06T19:58:28Z","pull_request":{"url":"https://api.github.com/repos/Microsoft/TypeScript/pulls/3622","html_url":"https://github.com/Microsoft/TypeScript/pull/3622","diff_url":"https://github.com/Microsoft/TypeScript/pull/3622.diff","patch_url":"https://github.com/Microsoft/TypeScript/pull/3622.patch"},"body":"This PR implements intersection types, the logical complement of union types. A union type `A | B` represents an entity that has either type A or type B, whereas an intersection type `A & B` represents an entity that has both type A and type B.\r\n\r\n### Type Relationships\r\n\r\n* Identity: `A & A` is equivalent to `A`.\r\n* Commutativity: `A & B` is equivalent to `B & A` (except for call and construct signatures as noted below).\r\n* Associativity: `(A & B) & C` is equivalent to `A & (B & C)`.\r\n* Supertype collapsing: `A & B` is equivalent to `A` if `B` is a supertype of `A`.\r\n\r\n### Assignment compatibility\r\n\r\n* `A & B` is assignable to `X` if `A` is assignable to `X` or `B` is assignable to `X`.\r\n* `X` is assignable to `A & B` if `X` is assignable to `A` and `X` is assignable to `B`.\r\n\r\n### Properties and Index Signatures\r\n\r\nThe type `A & B` has a property `P` if `A` has a property `P` or `B` has a property `P`. If `A` has a property `P` of type `X` and `B` has a property `P` of type `Y`, then `A & B` has a property `P` of type `X & Y`.\r\n\r\nIndex signatures are similarly intersected.\r\n\r\n### Call and Construct Signatures\r\n\r\nIf `A` has a signature `F` and `B` has a signature `G`, then `A & B` has signatures `F` and `G` in that order (the order of signatures matter for purposes of overload resolution). Except for the order of signatures, the types `A & B` and `B & A` are equivalent.\r\n\r\n### Precedence\r\n\r\nSimilarly to expression operators, the `&` type operator has higher precedence than the `|` type operator. Thus `A & B | C & D` is parsed as `(A & B) | (C & D)`.\r\n\r\n### Primitive Types\r\n\r\nIt is possible to intersect primitive types (e.g. `string & number`), but it is not possible to actually create values of such types (other than `undefined`). Because such types can result from instantiation of generic types (which is performed lazily), it is not possible to consistently detect and error on the operations that create the types.\r\n\r\n### Examples\r\n\r\n```typescript\r\nfunction extend<T, U>(first: T, second: U): T & U {\r\n    let result = <T & U> {};\r\n    for (let id in first) {\r\n        result[id] = first[id];\r\n    }\r\n    for (let id in second) {\r\n        if (!result.hasOwnProperty(id)) {\r\n            result[id] = second[id];\r\n        }\r\n    }\r\n    return result;\r\n}\r\n\r\nvar x = extend({ a: \"hello\" }, { b: 42 });\r\nvar s = x.a;\r\nvar n = x.b;\r\n```\r\n\r\n```typescript\r\ntype LinkedList<T> = T & { next: LinkedList<T> };\r\n\r\ninterface Person {\r\n    name: string;\r\n}\r\n\r\nvar people: LinkedList<Person>;\r\nvar s = people.name;\r\nvar s = people.next.name;\r\nvar s = people.next.next.name;\r\nvar s = people.next.next.next.name;\r\n```\r\n\r\n```typescript\r\ninterface A { a: string }\r\ninterface B { b: string }\r\ninterface C { c: string }\r\n\r\nvar abc: A & B & C;\r\nabc.a = \"hello\";\r\nabc.b = \"hello\";\r\nabc.c = \"hello\";\r\n\r\ninterface X { x: A }\r\ninterface Y { x: B }\r\ninterface Z { x: C }\r\n\r\nvar xyz: X & Y & Z;\r\nxyz.x.a = \"hello\";\r\nxyz.x.b = \"hello\";\r\nxyz.x.c = \"hello\";\r\n\r\ntype F1 = (x: string) => string;\r\ntype F2 = (x: number) => number;\r\n\r\nvar f: F1 & F2;\r\nvar s = f(\"hello\");\r\nvar n = f(42);\r\n```\r\n\r\nFixes #1256."},"comment":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/comments/126708728","html_url":"https://github.com/Microsoft/TypeScript/pull/3622#issuecomment-126708728","issue_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/3622","id":126708728,"user":{"login":"Artazor","id":185374,"avatar_url":"https://avatars.githubusercontent.com/u/185374?v=3","gravatar_id":"","url":"https://api.github.com/users/Artazor","html_url":"https://github.com/Artazor","followers_url":"https://api.github.com/users/Artazor/followers","following_url":"https://api.github.com/users/Artazor/following{/other_user}","gists_url":"https://api.github.com/users/Artazor/gists{/gist_id}","starred_url":"https://api.github.com/users/Artazor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Artazor/subscriptions","organizations_url":"https://api.github.com/users/Artazor/orgs","repos_url":"https://api.github.com/users/Artazor/repos","events_url":"https://api.github.com/users/Artazor/events{/privacy}","received_events_url":"https://api.github.com/users/Artazor/received_events","type":"User","site_admin":false},"created_at":"2015-07-31T14:28:51Z","updated_at":"2015-07-31T14:28:51Z","body":"Let's consider following interfaces\r\n\r\n```TypeScript\r\ninterface Base { \r\n    prop: string \r\n}\r\n\r\ninterface Container<T> { \r\n    put(item: T);\r\n    get(): T; \r\n}\r\n```\r\n\r\ncan we use:\r\n```TypeScript\r\nclass Some<TItem extends Base, TContainer extends Container<Base>> {\r\n       container:  TContainer & Container<TItem>;\r\n}\r\n\r\n```\r\nto emulate unsupported\r\n```TypeScript\r\nclass Some<TItem extends Base, TContainer extends Container<TItem>> {\r\n       container:  TContainer\r\n}\r\n```\r\n\r\n?"}}