{"action":"created","issue":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/1446","labels_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/1446/labels{/name}","comments_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/1446/comments","events_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/1446/events","html_url":"https://github.com/Microsoft/TypeScript/issues/1446","id":51631706,"number":1446,"title":"No common supertype between {optional, optional} and {required, absent}","user":{"login":"JsonFreeman","id":8052525,"avatar_url":"https://avatars.githubusercontent.com/u/8052525?v=3","gravatar_id":"","url":"https://api.github.com/users/JsonFreeman","html_url":"https://github.com/JsonFreeman","followers_url":"https://api.github.com/users/JsonFreeman/followers","following_url":"https://api.github.com/users/JsonFreeman/following{/other_user}","gists_url":"https://api.github.com/users/JsonFreeman/gists{/gist_id}","starred_url":"https://api.github.com/users/JsonFreeman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JsonFreeman/subscriptions","organizations_url":"https://api.github.com/users/JsonFreeman/orgs","repos_url":"https://api.github.com/users/JsonFreeman/repos","events_url":"https://api.github.com/users/JsonFreeman/events{/privacy}","received_events_url":"https://api.github.com/users/JsonFreeman/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/Microsoft/TypeScript/labels/Breaking%20Change","name":"Breaking Change","color":"eb6420"},{"url":"https://api.github.com/repos/Microsoft/TypeScript/labels/Bug","name":"Bug","color":"e11d21"},{"url":"https://api.github.com/repos/Microsoft/TypeScript/labels/Question","name":"Question","color":"d4c5f9"},{"url":"https://api.github.com/repos/Microsoft/TypeScript/labels/Spec","name":"Spec","color":"207de5"}],"state":"open","locked":false,"assignee":{"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},"milestone":{"url":"https://api.github.com/repos/Microsoft/TypeScript/milestones/7","labels_url":"https://api.github.com/repos/Microsoft/TypeScript/milestones/7/labels","id":874650,"number":7,"title":"TypeScript 1.5","description":"","creator":{"login":"mhegazy","id":8000722,"avatar_url":"https://avatars.githubusercontent.com/u/8000722?v=3","gravatar_id":"","url":"https://api.github.com/users/mhegazy","html_url":"https://github.com/mhegazy","followers_url":"https://api.github.com/users/mhegazy/followers","following_url":"https://api.github.com/users/mhegazy/following{/other_user}","gists_url":"https://api.github.com/users/mhegazy/gists{/gist_id}","starred_url":"https://api.github.com/users/mhegazy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mhegazy/subscriptions","organizations_url":"https://api.github.com/users/mhegazy/orgs","repos_url":"https://api.github.com/users/mhegazy/repos","events_url":"https://api.github.com/users/mhegazy/events{/privacy}","received_events_url":"https://api.github.com/users/mhegazy/received_events","type":"User","site_admin":false},"open_issues":59,"closed_issues":31,"state":"open","created_at":"2014-11-20T18:06:13Z","updated_at":"2015-01-22T23:36:07Z","due_on":null,"closed_at":null},"comments":4,"created_at":"2014-12-11T00:45:00Z","updated_at":"2015-01-23T02:16:51Z","closed_at":null,"body":"We made the change that an object type with a missing property cannot be a subtype of an object with an optional property. This made subtype choose better results in some cases, because it fixed cases of nonantisymmetry in the subtype relation. But now there are cases where you get an error in type argument inference because a pair of type has no common supertype.\r\n```ts\r\ninterface I {\r\n    a?: string;\r\n    b?: string;\r\n}\r\n\r\nvar i: I;\r\n\r\nfunction foo<T>(p1: T, p2: T) { }\r\n\r\nfoo(i, { a: \"\" }); // Error because neither type is a supertype of the other\r\n```\r\n\r\nOne interpretation is that in this case `I` should be the common supertype. To make this happen, we would say that instead of a missing property being a supertype of an optional, it is a subtype. In this view, missing and required are both specific cases of optional, and optional is a supertype of both.\r\n\r\nAnother fix is a change in type argument inference. If finding a common supertype does not yield a result, we can have another round where we use assignability. In the above example, this would not produce an error, since the object literal is assignable to `I`. \r\n\r\nThe issue here is that it may lead to results that depend on the order of the arguments. Both would select the first type in the following case:\r\n```ts\r\ninterface I1 {\r\n   a?: string\r\n}\r\ninterface I2 {\r\n   b?: string\r\n}\r\nvar i1: I1, i2: I2;\r\nfoo(i1, i2);\r\n```\r\nBoth proposed fixes would choose I1 because it is first, whereas now we at least get an error consistently no matter the argument order."},"comment":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/comments/71137295","html_url":"https://github.com/Microsoft/TypeScript/issues/1446#issuecomment-71137295","issue_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/1446","id":71137295,"user":{"login":"JsonFreeman","id":8052525,"avatar_url":"https://avatars.githubusercontent.com/u/8052525?v=3","gravatar_id":"","url":"https://api.github.com/users/JsonFreeman","html_url":"https://github.com/JsonFreeman","followers_url":"https://api.github.com/users/JsonFreeman/followers","following_url":"https://api.github.com/users/JsonFreeman/following{/other_user}","gists_url":"https://api.github.com/users/JsonFreeman/gists{/gist_id}","starred_url":"https://api.github.com/users/JsonFreeman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JsonFreeman/subscriptions","organizations_url":"https://api.github.com/users/JsonFreeman/orgs","repos_url":"https://api.github.com/users/JsonFreeman/repos","events_url":"https://api.github.com/users/JsonFreeman/events{/privacy}","received_events_url":"https://api.github.com/users/JsonFreeman/received_events","type":"User","site_admin":false},"created_at":"2015-01-23T02:16:51Z","updated_at":"2015-01-23T02:16:51Z","body":"One thing that occurs to me, is that the case where there are no inference candidates would give a different result with the new scheme:\r\n```ts\r\ninterface WithOptional<T> {\r\n    x?: T;\r\n}\r\ndeclare function foo<T>(p1: WithOptional<T>): T;\r\nfoo({}); // Used to infer {}, now we would infer any\r\n\r\ninterface WithOptionalAndUnion<T> {\r\n     x?: T // primary\r\n     y: string | T; // secondary\r\n}\r\ndeclare function bar<T>(p1: WithOptionalAndUnion<T>): T;\r\nbar({ y: \"\" }); // Used to infer string, now, we would infer any\r\n```"}}