{"id":25000155,"url":"https://github.com/thinkmill/emery","last_synced_at":"2025-04-07T17:09:22.786Z","repository":{"id":37421182,"uuid":"491323807","full_name":"Thinkmill/emery","owner":"Thinkmill","description":"💎 Polish for the rough parts of TypeScript","archived":false,"fork":false,"pushed_at":"2024-06-02T00:12:15.000Z","size":658,"stargazers_count":82,"open_issues_count":1,"forks_count":1,"subscribers_count":12,"default_branch":"main","last_synced_at":"2025-04-03T02:42:47.583Z","etag":null,"topics":["typescript","utilities"],"latest_commit_sha":null,"homepage":"https://emery-ts.vercel.app/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Thinkmill.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-12T01:26:19.000Z","updated_at":"2025-01-19T11:30:13.000Z","dependencies_parsed_at":"2024-01-16T01:00:18.203Z","dependency_job_id":"95b6dc4c-c34b-4145-b719-0a2043ee6aec","html_url":"https://github.com/Thinkmill/emery","commit_stats":{"total_commits":57,"total_committers":5,"mean_commits":11.4,"dds":0.5789473684210527,"last_synced_commit":"267db2b4e84e33a20347a1dfd9b58304221a39d6"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Thinkmill%2Femery","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Thinkmill%2Femery/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Thinkmill%2Femery/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Thinkmill%2Femery/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Thinkmill","download_url":"https://codeload.github.com/Thinkmill/emery/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247694876,"owners_count":20980733,"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":["typescript","utilities"],"created_at":"2025-02-04T19:31:39.004Z","updated_at":"2025-04-07T17:09:22.761Z","avatar_url":"https://github.com/Thinkmill.png","language":"TypeScript","readme":"# Emery\n\n\u003ca href=\"https://emery-ts.vercel.app/\"\u003e\n  \u003cimg alt=\"Polish for the rough parts of TypeScript\" src=\".github/assets/banner.svg\"\u003e\n\u003c/a\u003e\n\u003cp\u003e\n  \u003ca title=\"View on npm\" href=\"https://www.npmjs.com/package/emery\"\u003e\n    \u003cimg alt=\"npm version\" src=\"https://img.shields.io/npm/v/emery.svg?style=for-the-badge\u0026labelColor=0869B8\"\u003e\n  \u003c/a\u003e\n  \u003ca title=\"View the project license\" href=\"LICENSE\"\u003e\n    \u003cimg alt=\"License SDPX identifier\" src=\"https://img.shields.io/npm/l/emery.svg?style=for-the-badge\u0026labelColor=579805\"\u003e\n  \u003c/a\u003e\n  \u003ca title=\"View emery website\" href=\"https://emery-ts.vercel.app/\"\u003e\n    \u003cimg alt=\"Website\" src=\"https://img.shields.io/badge/Website-2F6BFF.svg?style=for-the-badge\u0026logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBjbGFzcz0iZmVhdGhlciBmZWF0aGVyLWdsb2JlIj48Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSIxMCI+PC9jaXJjbGU+PGxpbmUgeDE9IjIiIHkxPSIxMiIgeDI9IjIyIiB5Mj0iMTIiPjwvbGluZT48cGF0aCBkPSJNMTIgMmExNS4zIDE1LjMgMCAwIDEgNCAxMCAxNS4zIDE1LjMgMCAwIDEtNCAxMCAxNS4zIDE1LjMgMCAwIDEtNC0xMCAxNS4zIDE1LjMgMCAwIDEgNC0xMHoiPjwvcGF0aD48L3N2Zz4=\u0026labelColor=0737ad\u0026locoColor=white\u0026logoWidth=0\"\u003e\n  \u003c/a\u003e\n  \u003ca title=\"Visit Thinkmill\" href=\"https://www.thinkmill.com.au/open-source?utm_campaign=github-emery\"\u003e\n    \u003cimg alt=\"A Thinkmill project\" src=\"https://img.shields.io/badge/A%20Thinkmill%20Project-ed0000.svg?style=for-the-badge\u0026logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTg2IiBoZWlnaHQ9IjU4NiIgdmlld0JveD0iMCAwIDU4NiA1ODYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xOTk2XzQwNikiPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTU4NiAyOTNDNTg2IDQ1NC44MTkgNDU0LjgxOSA1ODYgMjkzIDU4NkMxMzEuMTgxIDU4NiAwIDQ1NC44MTkgMCAyOTNDMCAxMzEuMTgxIDEzMS4xODEgMCAyOTMgMEM0NTQuODE5IDAgNTg2IDEzMS4xODEgNTg2IDI5M1pNMjA1Ljc3NiAzNTguOTQ0QzE5MS4zNzYgMzU4Ljk0NCAxODUuOTA0IDM1Mi4zMiAxODUuOTA0IDMzNS45MDRWMjYyLjc1MkgyMTQuNDE2VjIzNy42OTZIMTg1LjkwNFYyMDEuMTJIMTUzLjA3MlYyMzcuNjk2SDEyOC41OTJWMjYyLjc1MkgxNTMuMDcyVjM0MC44QzE1My4wNzIgMzcyLjc2OCAxNjYuNjA4IDM4NS43MjggMTk3LjQyNCAzODUuNzI4QzIwMy40NzIgMzg1LjcyOCAyMTAuOTYgMzg0LjU3NiAyMTUuODU2IDM4My4xMzZWMzU3LjUwNEMyMTMuNTUyIDM1OC4zNjggMjA5LjUyIDM1OC45NDQgMjA1Ljc3NiAzNTguOTQ0Wk00MDcuMzc2IDIzNC4yNEMzODUuMiAyMzQuMjQgMzcxLjA4OCAyNDQuMDMyIDM2MC40MzIgMjYwLjczNkMzNTIuOTQ0IDI0My40NTYgMzM3LjM5MiAyMzQuMjQgMzE3LjIzMiAyMzQuMjRDMjk5Ljk1MiAyMzQuMjQgMjg2Ljk5MiAyNDEuMTUyIDI3Ni42MjQgMjU1LjI2NEgyNzYuMDQ4VjIzNy42OTZIMjQ0LjY1NlYzODRIMjc3LjQ4OFYzMDUuNjY0QzI3Ny40ODggMjc3LjQ0IDI4OC43MiAyNjAuNzM2IDMwOC4zMDQgMjYwLjczNkMzMjUuMjk2IDI2MC43MzYgMzM0LjUxMiAyNzIuODMyIDMzNC41MTIgMjkzLjU2OFYzODRIMzY3LjM0NFYzMDUuMDg4QzM2Ny4zNDQgMjc3LjE1MiAzNzguODY0IDI2MC43MzYgMzk4LjE2IDI2MC43MzZDNDE0LjU3NiAyNjAuNzM2IDQyNC42NTYgMjcxLjEwNCA0MjQuNjU2IDI5Ny4wMjRWMzg0SDQ1Ny40ODhWMjkzLjg1NkM0NTcuNDg4IDI1NC40IDQzOC40OCAyMzQuMjQgNDA3LjM3NiAyMzQuMjRaIiBmaWxsPSJ3aGl0ZSIvPgo8L2c+CjxkZWZzPgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzE5OTZfNDA2Ij4KPHJlY3Qgd2lkdGg9IjU4NiIgaGVpZ2h0PSI1ODYiIGZpbGw9IndoaXRlIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg==\u0026labelColor=C60200\u0026locoColor=white\u0026logoWidth=0\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n💎 Polish for the rough parts of TypeScript.\n\nTypeScript is great but there's parts that are still rough around the edges, especially for developers who are new to the language.\n\n## Purpose and intent\n\nEmery is a small collection of utilities that improve DX without compromising static types.\n\n### Check for ambiguous types\n\nEmery exposes \"checks\" for dealing with ambiguous types.\n\nChecks are just predicates that can't be expressed as type guards, without enforcing opaque types.\n\n```ts\nimport { checkAll, isNonNegative, isInteger } from 'emery';\n\n/**\n * Along with some default check functions, we provide helpers\n * for managing combinations. The `checkAll` helper is a bit\n * like `pipe` for predicates.\n */\nexport const isNonNegativeInteger = checkAll(isNonNegative, isInteger);\n```\n\n### Assert the validity of props\n\nAn assertion declares that a condition be true before executing subsequent code, ensuring that whatever condition is checked must be true for the remainder of the containing scope.\n\n```ts\nimport { assert } from 'emery';\n\nimport { isNonNegativeInteger } from './path-to/check';\n\nfunction getThingByIndex(index: number) {\n  assert(isNonNegativeInteger(index));\n\n  return things[index]; // 🎉 Safely use the `index` argument!\n}\n```\n\n### Smooth over loose types\n\nUtility functions for smoothing over areas of TypeScript that are loosely typed.\n\nBecause of JavaScript's dynamic implementation the default TS behaviour is correct, but can be frustrating in certain situations.\n\n```ts\nimport { typedKeys } from 'emery';\n\nconst obj = { foo: 1, bar: 2 };\n\nconst thing = Object.keys(obj).map(key =\u003e {\n  return obj[key]; // 🚨 'string' can't be used to index...\n});\nconst thing2 = typedKeys(obj).map(key =\u003e {\n  return obj[key]; // 🎉 No more TypeScript issues!\n});\n```\n\n## Philosophy and motivation\n\nLike all good things, Emery started with curiosity. At [Thinkmill](https://thinkmill.com.au/) we have an internal Slack channel for TypeScript where a question was raised about how to offer consumers error messages that convey intent, not just cascading type failures.\n\nWhile that's not currently possible, it became apparent that there was demand for a solution. We also discovered that many developers were carrying around miscellaneous utilities for working with TypeScript between projects.\n\n---\n\n## License\n\nCopyright (c) 2023\n[Thinkmill Labs](https://www.thinkmill.com.au/labs?utm_campaign=github-emery)\nPty Ltd. Licensed under the MIT License.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthinkmill%2Femery","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthinkmill%2Femery","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthinkmill%2Femery/lists"}