From fdb1d16ef0d26ad1b18a5e491af4aafec668cb4f Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Thu, 16 Jan 2025 08:12:33 -0500 Subject: [PATCH 1/2] feat: add redux-toolkit-floating-promises example --- package-lock.json | 92 ++++++++++++++++++- .../redux-toolkit-floating-promises/README.md | 25 +++++ .../eslint.config.js | 27 ++++++ .../redux-toolkit-floating-promises/index.ts | 16 ++++ .../package.json | 26 ++++++ .../tsconfig.json | 8 ++ 6 files changed, 191 insertions(+), 3 deletions(-) create mode 100644 packages/redux-toolkit-floating-promises/README.md create mode 100644 packages/redux-toolkit-floating-promises/eslint.config.js create mode 100644 packages/redux-toolkit-floating-promises/index.ts create mode 100644 packages/redux-toolkit-floating-promises/package.json create mode 100644 packages/redux-toolkit-floating-promises/tsconfig.json diff --git a/package-lock.json b/package-lock.json index cef5231..bbeed6c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -703,6 +703,30 @@ "node": ">= 8" } }, + "node_modules/@reduxjs/toolkit": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.5.0.tgz", + "integrity": "sha512-awNe2oTodsZ6LmRqmkFhtb/KH03hUhxOamEQy411m3Njj3BbFvoBovxo4Q1cBWnV1ErprVj9MlF0UPXkng0eyg==", + "license": "MIT", + "dependencies": { + "immer": "^10.0.3", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.28.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.1.tgz", @@ -1004,9 +1028,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.10.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", - "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", + "version": "22.10.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.7.tgz", + "integrity": "sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg==", "dev": true, "license": "MIT", "dependencies": { @@ -2128,6 +2152,16 @@ "node": ">= 4" } }, + "node_modules/immer": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz", + "integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -2406,6 +2440,10 @@ "tslib": "^2.0.3" } }, + "node_modules/node-test-floating-promises": { + "resolved": "packages/node-test-floating-promises", + "link": true + }, "node_modules/optionator": { "version": "0.9.3", "license": "MIT", @@ -2618,6 +2656,25 @@ "dev": true, "license": "MIT" }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "license": "MIT" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "license": "MIT", + "peerDependencies": { + "redux": "^5.0.0" + } + }, + "node_modules/redux-toolkit-floating-promises": { + "resolved": "packages/redux-toolkit-floating-promises", + "link": true + }, "node_modules/require-from-string": { "version": "2.0.2", "dev": true, @@ -2626,6 +2683,12 @@ "node": ">=0.10.0" } }, + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", + "license": "MIT" + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -3664,6 +3727,29 @@ "typescript-eslint": "^8.18.0" } }, + "packages/node-test-floating-promises": { + "version": "0.0.0", + "license": "MIT", + "devDependencies": { + "@types/node": "^22.10.7", + "eslint": "^9.16.0", + "typescript": "^5.7.2", + "typescript-eslint": "^8.18.0" + } + }, + "packages/redux-toolkit-floating-promises": { + "version": "0.0.0", + "license": "MIT", + "dependencies": { + "@reduxjs/toolkit": "2.5.0" + }, + "devDependencies": { + "@types/node": "^22.10.7", + "eslint": "^9.16.0", + "typescript": "^5.7.2", + "typescript-eslint": "^8.18.0" + } + }, "packages/typed-rule-via-linter": { "version": "0.0.0", "license": "MIT", diff --git a/packages/redux-toolkit-floating-promises/README.md b/packages/redux-toolkit-floating-promises/README.md new file mode 100644 index 0000000..8b89e63 --- /dev/null +++ b/packages/redux-toolkit-floating-promises/README.md @@ -0,0 +1,25 @@ +# Example: `redux-toolkit` and Floating Promise Detection + +An example of using [`redux-toolkit`](https://redux-toolkit.js.org) along with the [`@typescript-eslint/no-floating-promises` rule](https://typescript-eslint.io/rules/no-floating-promises) enabled. +It uses the [`allowForKnownSafePromises` rule option](https://typescript-eslint.io/rules/no-floating-promises/#allowforknownsafepromises) to not report on RTK APIs that create a `SafePromise`, such as `createAsyncThunk`. + +## Setup + +```shell +npm i +``` + +## Usage + +```shell +npm run lint +``` + +There should be no lint reports. + +If you remove the `allowForKnownSafePromises` option from `eslint.config.js`, there will be: + +```plaintext +.../index.test.ts + 4:1 error Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator @typescript-eslint/no-floating-promises +``` \ No newline at end of file diff --git a/packages/redux-toolkit-floating-promises/eslint.config.js b/packages/redux-toolkit-floating-promises/eslint.config.js new file mode 100644 index 0000000..cdd6d87 --- /dev/null +++ b/packages/redux-toolkit-floating-promises/eslint.config.js @@ -0,0 +1,27 @@ +// @ts-check + +import eslint from "@eslint/js"; +import tseslint from "typescript-eslint"; + +export default tseslint.config( + eslint.configs.recommended, + tseslint.configs.recommendedTypeChecked, + { + languageOptions: { + parserOptions: { + projectService: { + allowDefaultProject: ['*.config.*'] + }, + }, + }, + rules: { + "@typescript-eslint/no-floating-promises": [ + "error", { + "allowForKnownSafePromises": [ + { "from": "package", "name": "SafePromise", "package": "@reduxjs/toolkit" } + ] + } + ] + } + } +); diff --git a/packages/redux-toolkit-floating-promises/index.ts b/packages/redux-toolkit-floating-promises/index.ts new file mode 100644 index 0000000..81eba26 --- /dev/null +++ b/packages/redux-toolkit-floating-promises/index.ts @@ -0,0 +1,16 @@ +import { configureStore, createAsyncThunk } from '@reduxjs/toolkit'; + +function reducer() { + // ... +} + +const store = configureStore({ reducer }); + +const exampleThunk = createAsyncThunk( + 'example', + async () => { + // ... + }, +); + +store.dispatch(exampleThunk()); diff --git a/packages/redux-toolkit-floating-promises/package.json b/packages/redux-toolkit-floating-promises/package.json new file mode 100644 index 0000000..fc0a59d --- /dev/null +++ b/packages/redux-toolkit-floating-promises/package.json @@ -0,0 +1,26 @@ +{ + "name": "redux-toolkit-floating-promises", + "version": "0.0.0", + "description": "Example of using `redux-toolkit` with `@typescript-eslint/no-floating-promises`'s `allowForKnownSafePromises` option.", + "main": "index.ts", + "repository": { + "directory": "packages/redux-toolkit-floating-promises", + "type": "git", + "url": "https://github.com/typescript-eslint/typescript-eslint-examples" + }, + "license": "MIT", + "devDependencies": { + "@types/node": "^22.10.7", + "eslint": "^9.16.0", + "typescript": "^5.7.2", + "typescript-eslint": "^8.18.0" + }, + "dependencies": { + "@reduxjs/toolkit": "2.5.0" + }, + "scripts": { + "lint": "eslint .", + "tsc": "tsc" + }, + "type": "module" +} diff --git a/packages/redux-toolkit-floating-promises/tsconfig.json b/packages/redux-toolkit-floating-promises/tsconfig.json new file mode 100644 index 0000000..5283fbc --- /dev/null +++ b/packages/redux-toolkit-floating-promises/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "module": "NodeNext", + "moduleResolution": "NodeNext", + "noEmit": true, + "strict": true + }, +} From 185fa5c6d3d9dfa6bcaa876f40195a36f0e348fe Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Fri, 17 Jan 2025 08:04:29 -0500 Subject: [PATCH 2/2] Add in two more rtk package allows too --- packages/redux-toolkit-floating-promises/eslint.config.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/redux-toolkit-floating-promises/eslint.config.js b/packages/redux-toolkit-floating-promises/eslint.config.js index cdd6d87..b418e95 100644 --- a/packages/redux-toolkit-floating-promises/eslint.config.js +++ b/packages/redux-toolkit-floating-promises/eslint.config.js @@ -18,7 +18,9 @@ export default tseslint.config( "@typescript-eslint/no-floating-promises": [ "error", { "allowForKnownSafePromises": [ - { "from": "package", "name": "SafePromise", "package": "@reduxjs/toolkit" } + { from: "package", name: "SafePromise", package: "@reduxjs/toolkit" }, + { from: 'package', name: 'SafePromise', package: '@reduxjs/toolkit/query' }, + { from: 'package', name: 'SafePromise', package: '@reduxjs/toolkit/query/react' }, ] } ] pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy