{"action":"closed","number":30499,"pull_request":{"url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/pulls/30499","id":230603781,"node_id":"MDExOlB1bGxSZXF1ZXN0MjMwNjAzNzgx","html_url":"https://github.com/DefinitelyTyped/DefinitelyTyped/pull/30499","diff_url":"https://github.com/DefinitelyTyped/DefinitelyTyped/pull/30499.diff","patch_url":"https://github.com/DefinitelyTyped/DefinitelyTyped/pull/30499.patch","issue_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/issues/30499","number":30499,"state":"closed","locked":false,"title":"Knockout - add readonly types for observables, observable arrays, and computeds","user":{"login":"Retsam","id":2281166,"node_id":"MDQ6VXNlcjIyODExNjY=","avatar_url":"https://avatars0.githubusercontent.com/u/2281166?v=4","gravatar_id":"","url":"https://api.github.com/users/Retsam","html_url":"https://github.com/Retsam","followers_url":"https://api.github.com/users/Retsam/followers","following_url":"https://api.github.com/users/Retsam/following{/other_user}","gists_url":"https://api.github.com/users/Retsam/gists{/gist_id}","starred_url":"https://api.github.com/users/Retsam/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Retsam/subscriptions","organizations_url":"https://api.github.com/users/Retsam/orgs","repos_url":"https://api.github.com/users/Retsam/repos","events_url":"https://api.github.com/users/Retsam/events{/privacy}","received_events_url":"https://api.github.com/users/Retsam/received_events","type":"User","site_admin":false},"body":"- [X] Use a meaningful title for the pull request. Include the name of the package modified.\r\n- [X] Test the change in your own code. (Compile and run.)\r\n- [X] Add or edit tests to reflect the change. (Run with `npm test`.)\r\n- [X] Follow the advice from the [readme](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/README.md#make-a-pull-request).\r\n- [X] Avoid [common mistakes](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/README.md#common-mistakes).\r\n- [X] Run `npm run lint package-name` (or `tsc` if no `tslint.json` is present).\r\n\r\nIf changing an existing definition:\r\n- [X] Provide a URL to documentation or source code which provides context for the suggested changes: https://knockoutjs.com/documentation/computedObservables.html\r\n- [X] Increase the version number in the header if appropriate.\r\n- [X] If you are making substantial changes, consider adding a `tslint.json` containing `{ \"extends\": \"dtslint/dt.json\" }`.\r\n\r\n---\r\n\r\nKnockout's current typings don't have any consideration for the idea of readonly.  In particular, `computed`s can be readonly:\r\n\r\n```ts\r\nconst observable = ko.observable(5);\r\n// A read only computed\r\nconst readOnlyComputed = ko.computed(() => observable()); \r\n\r\n// A read-write computed\r\nconst writableComputed = ko.computed({\r\n     read: () => observable(),\r\n     write: val => observable(val),\r\n});\r\n```\r\n\r\nUnfortunately the types don't distinguish between these and so `readOnlyComputed(10)` is valid, type-checked code, but fails with a runtime error.\r\n\r\nThis PR, unfortunately, does not fix that problem: I've written the changes that would fix it, but it created a prohibitive number of breaking changes in my codebase, and didn't want to break everyone's typings.\r\n\r\nBut it does at least introduce typings that can represent a readonly computed, so it is now possible to write:\r\n\r\n```ts\r\nconst readOnlyComputed: KnockoutReadonlyComputed<number> = ko.computed(() => observable()); \r\nreadOnlyComputed(10); // Type error!\r\n```\r\n\r\n---\r\n\r\nSimilarly, it introduces `KnockoutReadonlyObservable` and `KnockoutReadonlyObservableArray`.  Unlike `computed`, there isn't really such a concept as a read-only observable, in runtime; but just as it's useful to cast an actually-mutable-at-runtime array to Typescript's `ReadonlyArray` type, I find it useful to have readonly variants of `observable` and `observableArray` as well.  \r\n\r\nFor example, a function signature written as `function doSomething(observable: KnockoutReadonlyObservable<number>) {` conveys the intention that `doSomething` will not mutate the observable, only read from it or subscribe to it.  ","created_at":"2018-11-13T19:51:30Z","updated_at":"2018-11-19T19:47:03Z","closed_at":"2018-11-19T19:47:03Z","merged_at":"2018-11-19T19:47:03Z","merge_commit_sha":"1d74d5ac420b6470eeded06a9e7417fc0244b28a","assignee":null,"assignees":[],"requested_reviewers":[{"login":"borisyankov","id":867242,"node_id":"MDQ6VXNlcjg2NzI0Mg==","avatar_url":"https://avatars3.githubusercontent.com/u/867242?v=4","gravatar_id":"","url":"https://api.github.com/users/borisyankov","html_url":"https://github.com/borisyankov","followers_url":"https://api.github.com/users/borisyankov/followers","following_url":"https://api.github.com/users/borisyankov/following{/other_user}","gists_url":"https://api.github.com/users/borisyankov/gists{/gist_id}","starred_url":"https://api.github.com/users/borisyankov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/borisyankov/subscriptions","organizations_url":"https://api.github.com/users/borisyankov/orgs","repos_url":"https://api.github.com/users/borisyankov/repos","events_url":"https://api.github.com/users/borisyankov/events{/privacy}","received_events_url":"https://api.github.com/users/borisyankov/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[{"id":905334095,"node_id":"MDU6TGFiZWw5MDUzMzQwOTU=","url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/labels/Owner%20Approved","name":"Owner Approved","color":"0e8a16","default":false},{"id":395679059,"node_id":"MDU6TGFiZWwzOTU2NzkwNTk=","url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/labels/Revision%20needed","name":"Revision needed","color":"b60205","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/pulls/30499/commits","review_comments_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/pulls/30499/comments","review_comment_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/pulls/comments{/number}","comments_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/issues/30499/comments","statuses_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/statuses/2f4da334464c822dc61451f24abe6387239f2662","head":{"label":"Retsam:knockout-read-only-types","ref":"knockout-read-only-types","sha":"2f4da334464c822dc61451f24abe6387239f2662","user":{"login":"Retsam","id":2281166,"node_id":"MDQ6VXNlcjIyODExNjY=","avatar_url":"https://avatars0.githubusercontent.com/u/2281166?v=4","gravatar_id":"","url":"https://api.github.com/users/Retsam","html_url":"https://github.com/Retsam","followers_url":"https://api.github.com/users/Retsam/followers","following_url":"https://api.github.com/users/Retsam/following{/other_user}","gists_url":"https://api.github.com/users/Retsam/gists{/gist_id}","starred_url":"https://api.github.com/users/Retsam/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Retsam/subscriptions","organizations_url":"https://api.github.com/users/Retsam/orgs","repos_url":"https://api.github.com/users/Retsam/repos","events_url":"https://api.github.com/users/Retsam/events{/privacy}","received_events_url":"https://api.github.com/users/Retsam/received_events","type":"User","site_admin":false},"repo":{"id":43118907,"node_id":"MDEwOlJlcG9zaXRvcnk0MzExODkwNw==","name":"DefinitelyTyped","full_name":"Retsam/DefinitelyTyped","private":false,"owner":{"login":"Retsam","id":2281166,"node_id":"MDQ6VXNlcjIyODExNjY=","avatar_url":"https://avatars0.githubusercontent.com/u/2281166?v=4","gravatar_id":"","url":"https://api.github.com/users/Retsam","html_url":"https://github.com/Retsam","followers_url":"https://api.github.com/users/Retsam/followers","following_url":"https://api.github.com/users/Retsam/following{/other_user}","gists_url":"https://api.github.com/users/Retsam/gists{/gist_id}","starred_url":"https://api.github.com/users/Retsam/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Retsam/subscriptions","organizations_url":"https://api.github.com/users/Retsam/orgs","repos_url":"https://api.github.com/users/Retsam/repos","events_url":"https://api.github.com/users/Retsam/events{/privacy}","received_events_url":"https://api.github.com/users/Retsam/received_events","type":"User","site_admin":false},"html_url":"https://github.com/Retsam/DefinitelyTyped","description":"The repository for high quality TypeScript type definitions.","fork":true,"url":"https://api.github.com/repos/Retsam/DefinitelyTyped","forks_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/forks","keys_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/teams","hooks_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/hooks","issue_events_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/issues/events{/number}","events_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/events","assignees_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/assignees{/user}","branches_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/branches{/branch}","tags_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/tags","blobs_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/git/refs{/sha}","trees_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/statuses/{sha}","languages_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/languages","stargazers_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/stargazers","contributors_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/contributors","subscribers_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/subscribers","subscription_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/subscription","commits_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/commits{/sha}","git_commits_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/git/commits{/sha}","comments_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/comments{/number}","issue_comment_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/issues/comments{/number}","contents_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/contents/{+path}","compare_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/merges","archive_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/downloads","issues_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/issues{/number}","pulls_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/pulls{/number}","milestones_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/milestones{/number}","notifications_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/labels{/name}","releases_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/releases{/id}","deployments_url":"https://api.github.com/repos/Retsam/DefinitelyTyped/deployments","created_at":"2015-09-25T08:08:17Z","updated_at":"2017-03-07T06:41:29Z","pushed_at":"2018-11-13T20:02:12Z","git_url":"git://github.com/Retsam/DefinitelyTyped.git","ssh_url":"git@github.com:Retsam/DefinitelyTyped.git","clone_url":"https://github.com/Retsam/DefinitelyTyped.git","svn_url":"https://github.com/Retsam/DefinitelyTyped","homepage":"http://definitelytyped.org/","size":371233,"stargazers_count":0,"watchers_count":0,"language":"TypeScript","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"DefinitelyTyped:master","ref":"master","sha":"d1b0ac675b2e813b5ea258aeda4e91a1520927ca","user":{"login":"DefinitelyTyped","id":3637556,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM2Mzc1NTY=","avatar_url":"https://avatars1.githubusercontent.com/u/3637556?v=4","gravatar_id":"","url":"https://api.github.com/users/DefinitelyTyped","html_url":"https://github.com/DefinitelyTyped","followers_url":"https://api.github.com/users/DefinitelyTyped/followers","following_url":"https://api.github.com/users/DefinitelyTyped/following{/other_user}","gists_url":"https://api.github.com/users/DefinitelyTyped/gists{/gist_id}","starred_url":"https://api.github.com/users/DefinitelyTyped/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DefinitelyTyped/subscriptions","organizations_url":"https://api.github.com/users/DefinitelyTyped/orgs","repos_url":"https://api.github.com/users/DefinitelyTyped/repos","events_url":"https://api.github.com/users/DefinitelyTyped/events{/privacy}","received_events_url":"https://api.github.com/users/DefinitelyTyped/received_events","type":"Organization","site_admin":false},"repo":{"id":6093316,"node_id":"MDEwOlJlcG9zaXRvcnk2MDkzMzE2","name":"DefinitelyTyped","full_name":"DefinitelyTyped/DefinitelyTyped","private":false,"owner":{"login":"DefinitelyTyped","id":3637556,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM2Mzc1NTY=","avatar_url":"https://avatars1.githubusercontent.com/u/3637556?v=4","gravatar_id":"","url":"https://api.github.com/users/DefinitelyTyped","html_url":"https://github.com/DefinitelyTyped","followers_url":"https://api.github.com/users/DefinitelyTyped/followers","following_url":"https://api.github.com/users/DefinitelyTyped/following{/other_user}","gists_url":"https://api.github.com/users/DefinitelyTyped/gists{/gist_id}","starred_url":"https://api.github.com/users/DefinitelyTyped/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DefinitelyTyped/subscriptions","organizations_url":"https://api.github.com/users/DefinitelyTyped/orgs","repos_url":"https://api.github.com/users/DefinitelyTyped/repos","events_url":"https://api.github.com/users/DefinitelyTyped/events{/privacy}","received_events_url":"https://api.github.com/users/DefinitelyTyped/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/DefinitelyTyped/DefinitelyTyped","description":"The repository for high quality TypeScript type definitions.","fork":false,"url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped","forks_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/forks","keys_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/keys{/key_id}","collaborators_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/teams","hooks_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/hooks","issue_events_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/issues/events{/number}","events_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/events","assignees_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/assignees{/user}","branches_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/branches{/branch}","tags_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/tags","blobs_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/git/refs{/sha}","trees_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/git/trees{/sha}","statuses_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/statuses/{sha}","languages_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/languages","stargazers_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/stargazers","contributors_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/contributors","subscribers_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/subscribers","subscription_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/subscription","commits_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/commits{/sha}","git_commits_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/git/commits{/sha}","comments_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/comments{/number}","issue_comment_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/issues/comments{/number}","contents_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/contents/{+path}","compare_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/compare/{base}...{head}","merges_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/merges","archive_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/downloads","issues_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/issues{/number}","pulls_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/pulls{/number}","milestones_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/milestones{/number}","notifications_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/labels{/name}","releases_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/releases{/id}","deployments_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/deployments","created_at":"2012-10-05T16:39:45Z","updated_at":"2018-11-19T19:34:48Z","pushed_at":"2018-11-19T19:47:03Z","git_url":"git://github.com/DefinitelyTyped/DefinitelyTyped.git","ssh_url":"git@github.com:DefinitelyTyped/DefinitelyTyped.git","clone_url":"https://github.com/DefinitelyTyped/DefinitelyTyped.git","svn_url":"https://github.com/DefinitelyTyped/DefinitelyTyped","homepage":"http://definitelytyped.org/","size":379074,"stargazers_count":18596,"watchers_count":18596,"language":"TypeScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":15406,"mirror_url":null,"archived":false,"open_issues_count":2540,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":15406,"open_issues":2540,"watchers":18596,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/pulls/30499"},"html":{"href":"https://github.com/DefinitelyTyped/DefinitelyTyped/pull/30499"},"issue":{"href":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/issues/30499"},"comments":{"href":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/issues/30499/comments"},"review_comments":{"href":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/pulls/30499/comments"},"review_comment":{"href":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/pulls/30499/commits"},"statuses":{"href":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/statuses/2f4da334464c822dc61451f24abe6387239f2662"}},"author_association":"CONTRIBUTOR","merged":true,"mergeable":null,"rebaseable":null,"mergeable_state":"unknown","merged_by":{"login":"PranavSenthilnathan","id":12225508,"node_id":"MDQ6VXNlcjEyMjI1NTA4","avatar_url":"https://avatars3.githubusercontent.com/u/12225508?v=4","gravatar_id":"","url":"https://api.github.com/users/PranavSenthilnathan","html_url":"https://github.com/PranavSenthilnathan","followers_url":"https://api.github.com/users/PranavSenthilnathan/followers","following_url":"https://api.github.com/users/PranavSenthilnathan/following{/other_user}","gists_url":"https://api.github.com/users/PranavSenthilnathan/gists{/gist_id}","starred_url":"https://api.github.com/users/PranavSenthilnathan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PranavSenthilnathan/subscriptions","organizations_url":"https://api.github.com/users/PranavSenthilnathan/orgs","repos_url":"https://api.github.com/users/PranavSenthilnathan/repos","events_url":"https://api.github.com/users/PranavSenthilnathan/events{/privacy}","received_events_url":"https://api.github.com/users/PranavSenthilnathan/received_events","type":"User","site_admin":false},"comments":3,"review_comments":2,"maintainer_can_modify":false,"commits":4,"additions":87,"deletions":9,"changed_files":3}}
{"actor":{"display_login":"PranavSenthilnathan"}}