{"id":24204743,"url":"https://github.com/vkruglikov/rely-use-callback","last_synced_at":"2025-09-22T03:30:52.162Z","repository":{"id":153560467,"uuid":"629800229","full_name":"vkruglikov/rely-use-callback","owner":"vkruglikov","description":"Rely on typed useCallback in your ReactApp 🥂","archived":false,"fork":false,"pushed_at":"2023-04-22T18:26:05.000Z","size":165,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-14T08:51:44.319Z","etag":null,"topics":["react","typescript","usecallback"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/rely-use-callback","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/vkruglikov.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"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":"2023-04-19T03:48:17.000Z","updated_at":"2025-07-09T23:57:43.000Z","dependencies_parsed_at":null,"dependency_job_id":"7cfa7a64-6d3d-412c-a934-8f549418f856","html_url":"https://github.com/vkruglikov/rely-use-callback","commit_stats":{"total_commits":25,"total_committers":3,"mean_commits":8.333333333333334,"dds":0.24,"last_synced_commit":"9635b00933ad610573a43e27f1b8afa04f3f0200"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/vkruglikov/rely-use-callback","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vkruglikov%2Frely-use-callback","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vkruglikov%2Frely-use-callback/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vkruglikov%2Frely-use-callback/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vkruglikov%2Frely-use-callback/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vkruglikov","download_url":"https://codeload.github.com/vkruglikov/rely-use-callback/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vkruglikov%2Frely-use-callback/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276341197,"owners_count":25625431,"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","status":"online","status_checked_at":"2025-09-22T02:00:08.972Z","response_time":79,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["react","typescript","usecallback"],"created_at":"2025-01-13T23:18:05.536Z","updated_at":"2025-09-22T03:30:51.804Z","avatar_url":"https://github.com/vkruglikov.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rely-use-callback\n\nRely on typed `useCallback` in your ReactApp 🥂\n\n[![npm](https://img.shields.io/npm/v/rely-use-callback.svg)](https://www.npmjs.com/package/rely-use-callback)\n[![types](https://badgen.net/npm/types/rely-use-callback)](https://npmjs.org/package/rely-use-callback)\n[![License](https://badgen.net/github/license/vkruglikov/rely-use-callback)](https://github.com/vkruglikov/rely-use-callback/blob/master/LICENSE)\n\n\n##  ✨ Typed `useCallback`\nUse type `RelyCallback` to have type guard for `memo` components and `hooks` dependencies\n\n## 🤖 Motivation\n\nSometimes you need to check if a function exact is created by `useCallback`.\n \nFor example, this is may necessary for functions that are passed depending on other hooks\n\n```typescript jsx\nimport { useCallback, memo } from 'react';\n\n/** \n * Imagine that we have a hook that call some business logic in useEffect\n */\nconst useSomethinkToDoOnEffect = (todoFunction: () =\u003e void) =\u003e {\n    useEffect(() =\u003e {\n        todoFunction()\n    }, [\n        /** \n         * {@link todoFunction} passed to hook dependencies,\n         * so it is may important to save function \n         * reference by {@link useCallback} to keep business logic\n         */\n        todoFunction\n    ]);\n}\n\n/**\n * Also we can use {@link memo} HOC, where also important\n * pass function with save reference by {@link useCallback}\n */\nconst MemoizedComponent: FC\u003c{ onClick: () =\u003e void }\u003e = memo(({\n    onClick\n}) =\u003e \u003cChildComponent /\u003e)\n\nconst App = () =\u003e {\n    /** \n     * But currently TS types of {@link useSomethinkToDoOnEffect} \n     * can't warn us to use function created by {@link useCallback}\n     * \n     * So we can use both variants without ts errors\n     */\n    \n    useSomethinkToDoOnEffect(() =\u003e {});\n    \n    /** OR */\n    \n    const functionWithCallback = useCallback(() =\u003e {}, []);\n    useSomethinkToDoOnEffect(functionWithoutCallback);\n\n    return (\n        \u003cMemoizedComponent \n            /** nothing ts errors */\n            onClick={() =\u003e {}}\n        /\u003e\n    );\n}\n```\n\n## 😲 You probably don't need use this package\n\nI think, this code matches for you at 99 %, but up to you\n\n```typescript jsx\nimport { DependencyList, useCallback as _useCallback } from \"react\";\n\ninterface UseCallback\u003cT extends Function\u003e {}\n\nconst useCallback = \u003cT extends Function\u003e(\n    handler: T,\n    deps: DependencyList\n): UseCallback\u003cT\u003e =\u003e _useCallback(handler, deps);\n```\n\n## 📦 Install \u0026 Usage\n\n1️⃣ Install by running: `npm i rely-use-callback --save`\n\n2️⃣ Replace a `useCallback` from react with a `useCallback` from `rely-use-callback`:\n\n```diff typescript jsx\n- import { useCallback } from 'react';\n+ import { useCallback, RelyCallback } from 'rely-use-callback';\n\nconst useSomethinkToDoOnEffect = (  \n-    todoFunction: () =\u003e void\n+    todoFunction: RelyCallback\u003c() =\u003e void\u003e\n) =\u003e {  \n    useEffect(() =\u003e {  \n        todoFunction()  \n    }, [ todoFunction ]);  \n}\n\nconst MemoizedComponent:FC\u003c{  \n-    onClick: RelyCallback\u003c() =\u003e void\u003e\n+    onClick: () =\u003e void \n}\u003e = memo(() =\u003e \u003cChildComponent onClick={onClick} /\u003e)\n```\n\nWhen you use `useCallback` hook from `rely-use-callback`,\nyou can use type `RelyCallback` and save type guard on these cases\nand rely on callback function in your ReactApp\n\n## 💪💪💪 Extra more productive way\n\nA more productive way is to use typed `useCallback` in conjunction with [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks)\n\nMore about this eslint rules you can read on [plugin page](https://www.npmjs.com/package/eslint-plugin-react-hooks)\n```json\n{\n  \"rules\": {\n    \"react-hooks/rules-of-hooks\": \"error\",\n    \"react-hooks/exhaustive-deps\": \"warn\"\n  }\n}\n```\n\n## 🥂 License\n\n[MIT](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvkruglikov%2Frely-use-callback","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvkruglikov%2Frely-use-callback","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvkruglikov%2Frely-use-callback/lists"}