{"id":13763974,"url":"https://github.com/EnixCoda/safe-touch","last_synced_at":"2025-05-10T17:31:21.395Z","repository":{"id":65492335,"uuid":"140544055","full_name":"EnixCoda/safe-touch","owner":"EnixCoda","description":"⛓ Runtime optional chaining for JS","archived":false,"fork":false,"pushed_at":"2021-08-19T17:23:20.000Z","size":51,"stargazers_count":73,"open_issues_count":2,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-18T18:33:42.521Z","etag":null,"topics":["javascript-library","typescript-library"],"latest_commit_sha":null,"homepage":"https://npmjs.com/package/safe-touch","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/EnixCoda.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-07-11T08:19:04.000Z","updated_at":"2025-04-11T06:31:39.000Z","dependencies_parsed_at":"2023-01-25T19:35:15.348Z","dependency_job_id":null,"html_url":"https://github.com/EnixCoda/safe-touch","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EnixCoda%2Fsafe-touch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EnixCoda%2Fsafe-touch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EnixCoda%2Fsafe-touch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EnixCoda%2Fsafe-touch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/EnixCoda","download_url":"https://codeload.github.com/EnixCoda/safe-touch/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253453271,"owners_count":21911067,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript-library","typescript-library"],"created_at":"2024-08-03T15:01:02.892Z","updated_at":"2025-05-10T17:31:17.803Z","avatar_url":"https://github.com/EnixCoda.png","language":"TypeScript","funding_links":[],"categories":["Library"],"sub_categories":[],"readme":"# Safe Touch\n\nRetrieving deeply buried properties is a common problem in JavaScript, it could crash your application if you try to access a property that doesn't exist.\n\n```js\nconst state = { user: { name: \"EnixCoda\" } };\nconsole.log(state.user.name); // 'EnixCoda'\nstate.user = null;            // simulating logout\nconsole.log(state.user.name); // Uncaught TypeError: Cannot read property 'name' of null\n```\n\nSafe touch is a safe way to access deeply buried properties.\n\n```js\nconst $state = safeTouch(state);      // retrieving properties from $state is always safe\nconsole.log($state() === state);      // true; invoke to get the original value\n{\n  let { user: { name } } = $state;    // support native destructuring\n  console.log(name());                // 'EnixCoda'\n  console.log($state.user.name());    // 'EnixCoda'\n}\n\nObject.assign(state, { user: null })  // simulating logout\n{\n  let { user: { name } } = $state;    // support native destructuring\n  console.log(name());                // undefined; no errors!\n  console.log($state.user.name());    // undefined; no errors!\n}\n```\n\n[Playground](https://codesandbox.io/s/safe-touch-playground-o96vi)\n\nAvailable as `safe-touch` on [npm](https://www.npmjs.com/package/safe-touch).\n\n```shell\n\u003e yarn add safe-touch\n```\n\n## Why choose Safe Touch?\n- `state \u0026\u0026 state.user \u0026\u0026 state.user.name` is verbose.\n- wrapping with `try ... catch` is verbose and creates new code block.\n- lodash [`_.get`](https://lodash.com/docs/#get) has no TypeScript support.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FEnixCoda%2Fsafe-touch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FEnixCoda%2Fsafe-touch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FEnixCoda%2Fsafe-touch/lists"}