{"action":"created","issue":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/1860","labels_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/1860/labels{/name}","comments_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/1860/comments","events_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/1860/events","html_url":"https://github.com/Microsoft/TypeScript/issues/1860","id":55994728,"number":1860,"title":"Order of method overloading declaration matters when one parameter type extends the other","user":{"login":"hraban","id":137852,"avatar_url":"https://avatars.githubusercontent.com/u/137852?v=3","gravatar_id":"","url":"https://api.github.com/users/hraban","html_url":"https://github.com/hraban","followers_url":"https://api.github.com/users/hraban/followers","following_url":"https://api.github.com/users/hraban/following{/other_user}","gists_url":"https://api.github.com/users/hraban/gists{/gist_id}","starred_url":"https://api.github.com/users/hraban/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hraban/subscriptions","organizations_url":"https://api.github.com/users/hraban/orgs","repos_url":"https://api.github.com/users/hraban/repos","events_url":"https://api.github.com/users/hraban/events{/privacy}","received_events_url":"https://api.github.com/users/hraban/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/Microsoft/TypeScript/labels/By%20Design","name":"By Design","color":"fbca04"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-01-30T04:53:55Z","updated_at":"2015-01-30T05:04:54Z","closed_at":"2015-01-30T05:04:54Z","body":"Playing around with the type definitions for React 0.13 I ran into this problem:\r\n\r\n```typescript\r\ndeclare module Test {\r\n\tinterface Parent {\r\n\t\ty: number;\r\n\t}\r\n\tinterface Child extends Parent {\r\n\t\tz: string;\r\n\t}\r\n\t\r\n\tinterface ParentDeriv {\r\n\t\tyderiv: number;\r\n\t}\r\n\tinterface ChildDeriv extends ParentDeriv {\r\n\t\tzderiv: string;\r\n\t}\r\n\t\r\n\tinterface Api {\r\n\t\tmakeParent(): Parent;\r\n\t\tmakeChild(): Child;\r\n\t\tmeth(element: Parent): ParentDeriv;\r\n\t\tmeth(element: Child): ChildDeriv;\r\n\t}\r\n\t\r\n\tvar api: Api;\r\n}\r\n\r\nvar x = Test.api.meth(Test.api.makeParent());\r\nx.zderiv; // Should be: error. Is: error.\r\nvar y = Test.api.meth(Test.api.makeChild()); // takes wrong method.\r\ny.zderiv; // Should be: ok. Is: error. y is inferred ParentDeriv.\r\n```\r\n\r\nBut if you flip the method declarations around, it works fine:\r\n\r\n```typescript\r\ndeclare module Test {\r\n\tinterface Parent {\r\n\t\ty: number;\r\n\t}\r\n\tinterface Child extends Parent {\r\n\t\tz: string;\r\n\t}\r\n\t\r\n\tinterface ParentDeriv {\r\n\t\tyderiv: number;\r\n\t}\r\n\tinterface ChildDeriv extends ParentDeriv {\r\n\t\tzderiv: string;\r\n\t}\r\n\t\r\n\tinterface Api {\r\n\t\tmakeParent(): Parent;\r\n\t\tmakeChild(): Child;\r\n\t\t// Note order: child class first\r\n\t\tmeth(element: Child): ChildDeriv;\r\n\t\tmeth(element: Parent): ParentDeriv;\r\n\t}\r\n\t\r\n\tvar api: Api;\r\n}\r\n\r\nvar x = Test.api.meth(Test.api.makeParent());\r\nx.zderiv; // Should be: error. Is: error.\r\nvar y = Test.api.meth(Test.api.makeChild());\r\ny.zderiv; // Should be: ok. Is: ok.\r\n```\r\n\r\nThis is a bug, right? With TS I'm never sure..\r\n\r\nTested with 1.4 (Playground and local)"},"comment":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/comments/72154737","html_url":"https://github.com/Microsoft/TypeScript/issues/1860#issuecomment-72154737","issue_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/1860","id":72154737,"user":{"login":"RyanCavanaugh","id":6685088,"avatar_url":"https://avatars.githubusercontent.com/u/6685088?v=3","gravatar_id":"","url":"https://api.github.com/users/RyanCavanaugh","html_url":"https://github.com/RyanCavanaugh","followers_url":"https://api.github.com/users/RyanCavanaugh/followers","following_url":"https://api.github.com/users/RyanCavanaugh/following{/other_user}","gists_url":"https://api.github.com/users/RyanCavanaugh/gists{/gist_id}","starred_url":"https://api.github.com/users/RyanCavanaugh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RyanCavanaugh/subscriptions","organizations_url":"https://api.github.com/users/RyanCavanaugh/orgs","repos_url":"https://api.github.com/users/RyanCavanaugh/repos","events_url":"https://api.github.com/users/RyanCavanaugh/events{/privacy}","received_events_url":"https://api.github.com/users/RyanCavanaugh/received_events","type":"User","site_admin":false},"created_at":"2015-01-30T05:04:54Z","updated_at":"2015-01-30T05:04:54Z","body":"Overload resolution absolutely matters. The rule is that the first applicable overload is chosen. We tried a bunch of other rules and this was the only one anyone could ever make sense of in practice.\r\n\r\nThis does mean that it's possible to write overloads which are \"unreachable\" by putting the general signature before the more specific overload; care needs to be taken to put the more-specific overloads first."}}