{"action":"opened","issue":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/18228","repository_url":"https://api.github.com/repos/Microsoft/TypeScript","labels_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/18228/labels{/name}","comments_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/18228/comments","events_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/18228/events","html_url":"https://github.com/Microsoft/TypeScript/issues/18228","id":254872616,"number":18228,"title":"Less restrictive object type","user":{"login":"SaschaNaz","id":3396686,"avatar_url":"https://avatars2.githubusercontent.com/u/3396686?v=4","gravatar_id":"","url":"https://api.github.com/users/SaschaNaz","html_url":"https://github.com/SaschaNaz","followers_url":"https://api.github.com/users/SaschaNaz/followers","following_url":"https://api.github.com/users/SaschaNaz/following{/other_user}","gists_url":"https://api.github.com/users/SaschaNaz/gists{/gist_id}","starred_url":"https://api.github.com/users/SaschaNaz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SaschaNaz/subscriptions","organizations_url":"https://api.github.com/users/SaschaNaz/orgs","repos_url":"https://api.github.com/users/SaschaNaz/repos","events_url":"https://api.github.com/users/SaschaNaz/events{/privacy}","received_events_url":"https://api.github.com/users/SaschaNaz/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2017-09-03T12:50:01Z","updated_at":"2017-09-03T12:50:01Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"### New behavior\r\n\r\nNo property existence check for `object` type.\r\n\r\n```ts\r\nlet foo: object;\r\nfoo.bar; // no error\r\n```\r\n\r\n### Rationale\r\n\r\nThe current `object` type is useful when used to type function arguments but not very useful on object members. See this IDL:\r\n\r\n```webidl\r\n[SecureContext]\r\ninterface PaymentResponse {\r\n    [Default] object        toJSON();\r\n\r\n    readonly attribute DOMString       requestId;\r\n    readonly attribute DOMString       methodName;\r\n    readonly attribute object          details;\r\n    readonly attribute PaymentAddress? shippingAddress;\r\n    readonly attribute DOMString?      shippingOption;\r\n    readonly attribute DOMString?      payerName;\r\n    readonly attribute DOMString?      payerEmail;\r\n    readonly attribute DOMString?      payerPhone;\r\n\r\n    Promise<void> complete(optional PaymentComplete result = \"unknown\");\r\n};\r\n```\r\n\r\nHere, the `details` member can be any \"object\" depending on payment method behavior. Current lib.d.ts defines this member as `any` so that a user can access any untyped members.\r\n\r\n```ts\r\nlet response: PaymentResponse;\r\nlet { details } = response;\r\ndetails.anImplementationDependentMemberName; // great\r\n```\r\n\r\nBut `any` means it can be `boolean`, `number`, `string` or even `null` or `undefined`.\r\n\r\n```ts\r\nif (typeof details === \"number\") {\r\n  // `details` is resolved as `number` but really should be `never` here\r\n}\r\ndetails++; // no error, :(\r\n```\r\n\r\nA language service should be able to warn on these cases while still allowing arbitrary member accesses. Allowing such free accesses on `object` type will help here:\r\n\r\n```ts\r\ndetails.anImplementationDependentMemberName; // still great\r\nif (typeof details === \"number\") {\r\n  // it cannot be a number, so `never` here\r\n}\r\ndetails++; // error now :D\r\n```\r\n\r\n### Hey, a `function` can also be an `object` in TS!\r\n\r\nYes, but I don't think the fact will cause any problem as functions can also have arbitrary members."}}
{"actor":{"display_login":"SaschaNaz"}}