ESLint 修改点整理

ESLint 为团队和项目带来的益处,这里不多说,本文主要是个人近期修改项目代码一些错误修改整理的内容。

备注:尽量使用默认 Prettier 规则,根据实际情况略有调整。项目技术栈 React, Redux, Redux-Sagas, TypeScript。

Plugin 列表

"plugin:react/recommended"
"plugin:@typescript-eslint/recommended"
"prettier/@typescript-eslint"
"plugin:prettier/recommended"

ERROR List

  • [Error] eslint@typescript-eslint/ban-ts-comment

    Do not use “// @ts-nocheck” because it alters compilation errors. Desc link

    TypeScript 提供 @ts-expect-error @ts-ignore @ts-nocheck @ts-check 指令注释方式,用来改变 tsc 编译时处理文件的方式,如果大量使用此类注释影响 TypeScript 的特性,既然使用 ts 就要拥抱它的特性,lint 中默认对 no-check 会按照 error 进行提示;可以根据实际情况调整规则,改为 warn

  • [Error] @typescript-eslint/ban-types

    Desc Link

    补充提示:

Don't use `{}` as a type. `{}` actually means "any non-nullish value".

- If you want a type meaning "any object", you probably want `Record<string, unknown>` instead.
- If you want a type meaning "any value", you probably want `unknown` instead.
  • [Error] react/jsx-no-target-blank

    Desc Link

    出于安全考虑,React 中产生新打开页面的链接,需要增加 rel='noreferrer' 用来保护原站。具体说明详见: Link

WARN List

  • [Warn] Missing return type on function.eslint@typescript-eslint/explicit-module-boundary-types

    desc link

    说明:针对函数的定义,建议每一个函数都要显式的表明函数返回值。这在 *.jsx, *.tsx 文件中,React 生命周期函数都提示,可以使用 eslint overrides 规则,只针对 *.js, *.ts 生效。

{
  "rules": {
    // disable the rule for all files
    "@typescript-eslint/explicit-module-boundary-types": "off"
  },
  "overrides": [
    {
      // enable the rule specifically for TypeScript files
      "files": ["*.js", "*.ts"],
      "rules": {
        "@typescript-eslint/explicit-module-boundary-types": "warn"
      }
    }
  ]
}
  • [Warn] @typescript-eslint/no-unused-vars

应该是最经常遇到的一个警告,定义了变量,下文没有使用。

个人建议:非关键算法或逻辑代码,当你阅读时没用,就删掉吧,可以保留注释,因为即使你想保留这段代码,以备不时之需,但是真到需要用到代码你再次阅读的时候,实现思路以及上下文联系可能已经相差很远。

Prettier 细节

  • 关于默认逗号的变化 link

Prettier 自动 v2.0.0 开始,将 trailingComma 默认配置由 none 改为 es5 ,在我看来是一种很好的方式。

举个例子,当 import 多个内容、一个对象需要增加属性、一个数组追加元素,如果默认已经追加了逗号,那么就可以直接追加,而不必要移动光标去前一行手动增加一个逗号,这样就增加了一些便利性,与此同时便于快速定位甚至避免由于一个逗号的引起的错误。

TS2322 自定义属性

import { AriaAttributes, DOMAttributes } from "react";

declare module "react" {
  interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> {
    // extends React's HTMLAttributes
    custom?: string;
  }
}

参考: https://dev.to/lukethacoder/use-custom-html-attribute-s-in-typescript-2co

TS2679

问题实例片段代码:

function* loadSimilar(skuId: string) {
  yield put({
    type: ActionTypes.REQUEST_SIMILAR.PENDING,
  });
  try {
    const { data } = yield API.querySimilar(skuId);
    yield put({
      type: ActionTypes.REQUEST_SIMILAR.SUCCESS,
      data,
    });
  } catch (error) {
    yield put({
      type: ActionTypes.REQUEST_SIMILAR.FAILURE,
    });
  }
}

function* watchSimilar() {
  yield takeEvery(ActionTypes.LOAD_SIMILAR, loadSimilar);
}

修改后代码:

- function* loadSimilar(skuId: string) {
+ function* loadSimilar({ skuId }: { type: string; skuId: string }) {
  yield put({
    type: ActionTypes.REQUEST_SIMILAR.PENDING,
  });
  try {
    const { data } = yield API.querySimilar(skuId);
    yield put({
      type: ActionTypes.REQUEST_SIMILAR.SUCCESS,
      data,
    });
  } catch (error) {
    yield put({
      type: ActionTypes.REQUEST_SIMILAR.FAILURE,
    });
  }
}

function* watchSimilar() {
  yield takeEvery(ActionTypes.LOAD_SIMILAR, loadSimilar);
}

解答:Redux-Saga 中 takeEvery 第二个参数是一个 action,所以定义 loadSimilar 时候需要遵循 TakeableChannel<unknown> ,定义 type。

参考: https://stackoverflow.com/a/60558041

切记,保证一路传递参数变量匹配,否则会出现无法赋值问题,例如下面代码:

- function* cartOptCheckOne({ param }: { type: string; param: any }) {
+ function* cartOptCheckOne({
+   // type = ActionTypes.OPT_CARTCHECKONE,
+   RequestParam,
+ }: {
+   type: string;
+   RequestParam: any;
+ }) {

外层触发 action 传参数代码如下:

this.props.optCartCheckOne({
  RequestParam: requestParam,
});

如果定义 cartOptCheckOne 使用 param 就会导致传递过程中因为变量名称不同无法解构,导致传参中断。

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章