Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Missing return type on function useAppDispatch

.eslintrc.js

module.exports = {
  root: true,
  extends: [
    '@react-native-community',
    'standard-with-typescript',
    'plugin:@typescript-eslint/recommended',
    'plugin:jest/recommended',
    'plugin:prettier/recommended',

    'plugin:import/recommended',

    'plugin:import/typescript',
  ],
  plugins: ['@typescript-eslint', 'prettier'],
  parser: '@typescript-eslint/parser',
  ignorePatterns: [
    'index.js',
    'metro.config.js',
    'react-native.config.js',
    'reactotron.config.js',
    'babel.config.js',
  ],
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    project: './tsconfig.json',
  },
  rules: {
    'prefer-const': 2,
    'no-var': 2,
    'no-new-object': 2,
    'object-shorthand': 2,
    'no-useless-rename': 2,
    'no-prototype-builtins': 2,
    'no-array-constructor': 2,
    'dot-notation': 0,
    semi: 0,
    'padding-line-between-statements': [
      'error',
      { blankLine: 'always', prev: '*', next: 'return' },
      { blankLine: 'always', prev: '*', next: 'break' },
      { blankLine: 'always', prev: '*', next: 'continue' },
      { blankLine: 'always', prev: '*', next: 'function' },
      { blankLine: 'always', prev: '*', next: 'block' },
    ],
    'lines-around-comment': [
      2,
      {
        beforeLineComment: true,
        allowBlockStart: true,
        allowObjectStart: true,
        allowObjectEnd: true,
      },
    ],
    'no-console': 1,
    'no-param-reassign': [
      'error',
      { props: true, ignorePropertyModificationsFor: ['state'] },
    ],

    // @react-native-community config is outdated as we have upgraded typescript
    // ^^ due to the above, all enums started throwing warning
    'no-shadow': 'off',

    // Import rules
    'import/order': [
      'error',
      {
        groups: [
          'builtin',
          'external',
          'internal',
          'parent',
          'sibling',
          'index',
          'object',
          'type',
        ],
        alphabetize: {
          order: 'asc',
        },
        'newlines-between': 'always',
      },
    ],
    'import/no-named-as-default-member': 'off',

    // typescript rules
    '@typescript-eslint/no-shadow': ['error'],
    '@typescript-eslint/strict-boolean-expressions': 'off',
    '@typescript-eslint/explicit-function-return-type': [
      'error',
      {
        allowExpressions: true,
        allowTypedFunctionExpressions: true,
      },
    ],
    '@typescript-eslint/naming-convention': [
      'error',
      {
        selector: 'property',
        format: ['snake_case', 'strictCamelCase', 'UPPER_CASE'],
      },
    ],
  },
  settings: {
    'import/parsers': {
      '@typescript-eslint/parser': ['.ts', '.tsx'],
    },
    'import/resolver': {
      typescript: {
        alwaysTryTypes: true,
      },
    },
  },
};

Store.ts

import { configureStore } from '@reduxjs/toolkit';

import usersReducer from '../features/users';

const store = configureStore({
  reducer: {
    users: usersReducer,
  },
});

export type AppDispatch = typeof store.dispatch;
export type RootState = ReturnType<typeof store.getState>;

export default store;

useStore.ts

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';

import { RootState, AppDispatch } from '../store/index';


export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;

() => useDispatch<AppDispatch>() expects me to provide a return type as @typescript-eslint/explicit-function-return-type is enabled. The return type can be seen by hovering over the constant useAppDispatch in VSCode but it would require frequent updates as it’s listing the store states.

How can I make the function avoid asking for return type as it’s already inferred without disabling the rule? Thank you.

Packages:

"react-redux": "^7.2.6",
"@types/react-redux": "^7.1.22",
"typescript": "^4.5.4",

>Solution :

Disable the rule, at least in this line. It is what it is.

Seriously, this rule is harmful.
You do not need to have each and every existing eslint rule active and rules that force annotation with certain types are especially harmful, causing you to remove available type information.

If something is wrong, you will still get a type error, just at usage of the function, not at definition.

There is one place where you need to annotate types and that is in function input positions – because there they cannot be inferred. Everything else is optional. Sometimes it helps readability, sometimes it actively hinders it. Use your mind at that point, don’t stick to a fixed rule.

Especially with Redux Toolkit, you get a lot of very specific types and manually annotating those will require you to either duplicate your code in types, or to annotate it in a way that you lose valuable information.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading