Skip to content

Conversation

@clock157
Copy link

@clock157 clock157 commented Mar 6, 2019

首先,感谢你的贡献!😄

新特性请提交至 feature 分支,其余可提交至 master 分支。
在一个维护者审核通过后合并。
请确保填写以下 pull request 的信息,谢谢!~

🤔 这个变动的性质是?

  • 新特性提交
  • 日常 bug 修复
  • 站点、文档改进
  • 组件样式改进
  • TypeScript 定义更新
  • 重构
  • 代码风格优化
  • 分支合并
  • 其他改动(是关于什么的改动?)

👻 需求背景

  1. 描述相关需求的来源,如相关的 issue 讨论链接。
  1. 要解决的具体问题。
    lint 统一是趋势,使用 eslint 来检查有更完善的规则,发现更多的习惯问题。

💡 解决方案和最终实现是?

  1. 实现
    混合检查 js 和 ts,目前社区没有看到很优雅的方案,暂时通过 override 的方式实现。

  2. 待讨论和解决的问题

  • 用 eslint 规则扫出了大量 error,我先全改为了 warning. 这其中哪些需要改,哪些需要关掉?
  • typescript 的最佳实践 rules?

📝 更新日志怎么写?

从用户角度描述具体变化,以及可能的 breaking change 和其他风险?

  1. 英文描述
    use eslint to lint typescript
  2. 中文描述(可选)

☑️ 请求合并前的自查清单

  • 文档已补充或无须补充
  • 代码演示已提供或无须提供
  • TypeScript 定义已补充或无须补充
  • Changelog 已提供或无须提供

@clock157 clock157 force-pushed the feat/ues_eslint-config-umi branch from 3db532a to 1b45d88 Compare March 6, 2019 13:56
@clock157 clock157 force-pushed the feat/ues_eslint-config-umi branch from 1b45d88 to 94924fd Compare March 6, 2019 13:59
@clock157
Copy link
Author

clock157 commented Mar 6, 2019

草稿中,有问题和需求可以告诉我。

@netlify
Copy link

netlify bot commented Mar 6, 2019

Deploy preview for ant-design ready!

Built with commit 3db532a425d8f3010eda4a63a92a58e983881704

https://deploy-preview-15236--ant-design.netlify.com

@netlify
Copy link

netlify bot commented Mar 6, 2019

Deploy preview for ant-design ready!

Built with commit 94924fd

https://deploy-preview-15236--ant-design.netlify.com

'no-return-assign': 1,
'no-plusplus': 1,
'react/no-access-state-in-setstate': 1,
'react/no-multi-comp': 1,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感觉还是 airbnb 的规则更全一点,这里还要自己维护 rules 列表。

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eslint-config-umi 是基于 airbnb 的,所以报了大量 error, 我将这部分 error 临时改成了 warning,其中很多的确是不规范的习惯可能要改,另外一些是可以忽略的。

扫了一下大概 2000 多个= =;

另外,我把这部分规则注释一下吧,便于理解,大家一起看下哪些要改哪些忽略。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不要改 warning,要么 error 要么去掉。

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ci还是可靠吧😂,这么大一项目,我怕改出问题。那我就按错误一个一个改,大家帮我cr下😅

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不着急改,先放出来看看哪些 errors,改动尽量少最好。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

另外 eslint-config-umi 貌似不是基于 airbnb 的。

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

之前不是,我发了一个2.0beta,基于airbnb,并支持了ts。我想通过pro或者antd把规则沉到eslint-config-umi,然后我们内部也可以用。

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我把这些error配合代码整理一下发出来。

@clock157
Copy link
Author

clock157 commented Mar 8, 2019

ant design eslint 规则探索

  1. class-methods-use-this 类方法需要使用 this
 getSelectedKeysName(direction: TransferDirection) {
    return direction === 'left' ? 'sourceSelectedKeys' : 'targetSelectedKeys';
 }

类方法中需要用到 this,不然这个方法可以直接写成静态方法,但是,静态方法在打包中有副作用,不利于 tree shaking,同样不推荐静态方法。

建议:off

  1. consistent-returns 一致的返回,需要都返回或者都不返回。
function getShowDateFromValue(value: RangePickerValue) {
  const [start, end] = value;
  // value could be an empty array, then we should not reset showDate
  if (!start && !end) {
    return;
  }
  const newEnd = end && end.isSame(start, 'month') ? end.clone().add(1, 'month') : end;
  return [start, newEnd] as RangePickerValue;
}

代码中第一个 return 没有返回值,如果返回一个 false 可以修复,但我们的实际的项目中大多没有这么强的约束,但是结合 typescript,可以更好的设计返回类型。

建议:off,数量:15

  1. global-require require 只能在顶层中使用
let enquire: any;
if (typeof window !== 'undefined') {
  ...
  window.matchMedia = window.matchMedia || matchMediaPolyfill;
  enquire = require('enquire.js');
}

在顶层更好识别依赖,同时在分支中的 require 会导致性能问题,可以拿到外面。如果某些场景必须使用,可以使用行内禁用 // eslint-disable-line

建议:error,数量:1

  1. import/first import 语句必须写在顶部
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';

if (typeof window !== 'undefined') {
  ...
  window.matchMedia = window.matchMedia || matchMediaPolyfill;
}

import * as React from 'react';

建议:error,数量:12 ,可被自动修复

  1. import/newline-after-import import 与代码体间需要空一行

建议:error,数量:46,可被自动修复

  1. import/no-duplicates 重复导入
import * as React from 'react';
import { createElement, Component } from 'react';

import * as React from 'react'; 这种写法不正确,之前被一个歪果仁纠正过

直接合并成一条语句

import React, { createElement, Component } from 'react';

建议:error,数量:6

  1. import/no-useless-path-segments 不必要的路径,多半是写多了

建议:error,数量: 2

  1. import/order 直接引用排在前,相对引用排后。

建议:error,数量:17,可自动修复

  1. jsx-a11y/alt-text img 等标签必须要有 alt 属性

建议:error,数量:1

  1. jsx-a11y/label-has-associated-control label 标签必须要有一个关联控件

建议:error?,数量:2

  1. jsx-a11y/label-has-for 过期,效果同上,建议关闭
  2. jsx-a11y/heading-has-content H 标签需要有内容
class Title extends React.Component<SkeletonTitleProps, any> {
  render() {
    const { prefixCls, className, width, style } = this.props;

    return <h3 className={classNames(prefixCls, className)} style={{ width, ...style }} />;
  }
}

如果没有内容,可以用其他不用 H。

建议:error,数量:1

  1. no-continue 不使用 continue

建议:error,数量:1

  1. no-else-return 不需要的 else

建议:off,数量:13

  1. no-extra-boolean-cast 不必要的 boolean 转化
    if (!!loading) {
      return;
    }

if 和 判断语句会自动转换为 boolean,不需要再转一次。

建议:error,数量:4

  1. no-fallthrough switch 语句禁止执行一个 case 后没有 break,再执行下一个 case
switch (size) {
      case 'large':
        sizeCls = 'lg';
        break;
      case 'small':
        sizeCls = 'sm';
      default:
        break;
    }

容易产生 bug,建议 case 完成后都执行一次 break

建议:error,数量:3,可自动修复

  1. no-lonely-if 在 else 中,不能有唯一 if 语句
if (menuMode === 'horizontal') {
        menuOpenAnimation = 'slide-up';
      } else if (menuMode === 'inline') {
        menuOpenAnimation = animation;
      } else {
        // When mode switch from inline
        // submenu should hide without animation
        if (this.switchingModeFromInline) {
          menuOpenAnimation = '';
          this.switchingModeFromInline = false;
        } else {
          menuOpenAnimation = 'zoom-big';
        }
      }

这里最后的 if 实际可以改成 else if,少包一层。

建议:error,数量:1,可自动修复

  1. no-multi-assign 不使用链式赋值
Modal.warning = Modal.warn = function(props: ModalFuncProps) {
  const config = {
    type: 'warning',
    icon: <Icon type="exclamation-circle" />,
    okCancel: false,
    ...props,
  };
  return confirm(config);
};

建议:error,数量:1

  1. no-nested-ternary 不使用嵌套三元运算符
React.cloneElement(ele, {
        className: classNames([
          ele.props.className,
          !reverse && !!pending
            ? idx === itemsCount - 2
              ? lastCls
              : ''
            : idx === itemsCount - 1
            ? lastCls
            : '',
          mode === 'alternate'
            ? idx % 2 === 0
              ? `${prefixCls}-item-left`
              : `${prefixCls}-item-right`
            : mode === 'right'
            ? `${prefixCls}-item-right`
            : '',
        ]),
      }),

嵌套后的三元运算符难以理解,复杂情况通过 if 语句更易读。

建议:error,数量:3

  1. no-param-reassign 不要对参数进行重新赋值
  onSuccess = (response: any, file: UploadFile) => {
    this.clearProgressTimer();
    try {
      if (typeof response === 'string') {
        response = JSON.parse(response);
      }
    } catch (e) {
      /* do nothing */
    }
  }

将参数重新赋值会让函数变的不纯,可能会导致一些不可预期的问题,某些时候需要对属性赋值可以使用配合参数 { "props": true }

建议:['error', { "props": true }],数量:27

  1. no-plusplus 不使用一元操作符自加自减
export default function wrapperRaf(callback: () => void, delayFrames: number = 1): number {
  const myId: number = id++;
  let restFrames: number = delayFrames;

  function internalCallback() {
    restFrames -= 1;

    if (restFrames <= 0) {
      callback();
      delete ids[id];
    } else {
      ids[id] = raf(internalCallback);
    }
  }

  ids[id] = raf(internalCallback);

  return myId;
}

for 循环中,i++ 的写法没问题,但是在其他时候,i+=1更容易理解,也不会因为换行和空格导致结果不一致。在本例中,myId 没有必要,其赋值也让人困惑。

建议: ['error', { allowForLoopAfterthoughts: true }],数量:2

  1. no-prototype-builtins 不直接使用对象上的原型方法
if (definingProperty || this === target.prototype || this.hasOwnProperty(key)) {
          return fn;
}

这个对象如果是 {hasOwnProperty: 123},这样写就会导致报错,正确的姿势是:

Object.prototype.hasOwnProperty.call(this, key)

建议:error,数量:1

  1. no-restricted-globals 禁止使用部分全局变量
const isNumeric = (value: any): boolean => {
  return !isNaN(parseFloat(value)) && isFinite(value);
};

举例:isNaNisFinite 不太直观,建议使用 Number.isNaN Number.isFinite

建议:error,数量:3

  1. no-return-assign 禁止在返回中赋值

在返回中赋值可能是想判断,但少写了等号。

建议:['error', 'except-parens']

  1. no-undef-init 不要初始化时赋值 undefined
let dangerousTheme: ThemeType | undefined = undefined;

定义变量时,会默认赋值为 undefined,不需要再显式赋值。

建议:error,数量:2,可自动修复

  1. no-underscore-dangle 禁用下划线打头

在之前,下划线打头意味着私有。但是这个规则不强制,因为在某些场景下,一个 function 如有多个参数,可以使用下划线参数名绕开变量必须被使用的规则。

建议:off,数量:5

  1. no-unneeded-ternary 没有必要的三元运算符
const resultListMatchInputWidth = showSearch.matchInputWidth === false ? false : true;

因为运算的结果本来就是 boolean,所以不必要用三元运算符

const resultListMatchInputWidth = !!showSearch.matchInputWidth

建议:error,数量:1,可自动修复

  1. no-unused-expressions 禁止没有用的表达式
const handleChange = (e: RadioChangeEvent | CheckboxChangeEvent) => {
        type === 'radio'
          ? this.handleRadioSelect(record, index, e)
          : this.handleSelect(record, index, e);
      };

这个规则是有意义的,但是ant design 中也常用到这种方式,用 if 更清晰,但是问题也不大。

建议:['error', { allowTernary: true }],数量:3

  1. no-useless-computed-key 禁用不需要的计算 key
export const svgBaseProps = {
  width: '1em',
  height: '1em',
  fill: 'currentColor',
  ['aria-hidden']: 'true',
  focusable: 'false',
};

这里的 key 没有计算,不需要用到中括号,有短横杠加引号即可。

建议:error,数量:3,可自动修复

  1. no-useless-escape 禁止不必要的转义
warning(
      !overlayProps.mode || overlayProps.mode === 'vertical',
      'Dropdown',
      `mode="${overlayProps.mode}" is not supported for Dropdown\'s Menu.`,
    );

一般出现在正则和模板变量中,这里的单引号不需要转义。

建议:error,数量:2

  1. no-useless-return 禁止不必要的 return
close = (e: EventType) => {
    if (this.props.visible !== undefined) {
      if (this.props.onClose) {
        this.props.onClose(e);
      }
      return;
    }
  };

没有返回值的 return 没有意义,不需要写

建议:error,数量:2

  1. no-void 不使用 void
this.setSelectedRowKeys(selectedRowKeys, {
        selectWay: 'onSelect',
        record,
        checked,
        changeRowKeys: void 0,
        nativeEvent,
      });

void 一般出现在压缩代码中,因为比 undefined 更短,虽然也有其他作用,但平时代码不建议使用。

建议:error,数量:2

  1. object-shorthand object 的简写
return api.open({ content, duration: duration, type, onClose });

本例中,duration 可简写

建议:error,数量:1,可自动修复

  1. operator-assignment 使用操作符赋值
  if (boxSizing === 'border-box') {
    // border-box: add border, since height = content + padding + border
    height = height + borderSize;
  } else if (boxSizing === 'content-box') {
    // remove padding, since height = content
    height = height - paddingSize;
  }

本例中,运算可写为:height += borderSize;

建议:错误,数量:3,可自动修复

  1. prefer-destructuring 倾向使用解构赋值
const fileList = this.state.fileList;

使用 es6 语法: const { fileList } = this.state;

建议:错误,数量:72,可自动修复

  1. prefer-spread 倾向使用展开
onChange.apply(
          null,
          this.prepareParamsArguments({
            ...this.state,
            selectionDirty: false,
            filters,
            pagination,
          }),
        );

这是 es2015 的写法,在 es6 中,通过展开语法更简单更好理解。

const params = this.prepareParamsArguments({
            ...this.state,
            selectionDirty: false,
            filters,
            pagination,
          });
onChange(...params);

建议:error,数量:4

  1. prefer-template 倾向使用字符串模板语法
const orientationPrefix = orientation.length > 0 ? '-' + orientation : orientation;

建议:error,数量:1,可自动修复

  1. react/button-has-type 按钮需要有一个类型
<button onClick={this.close} aria-label="Close" className={`${prefixCls}-close`}>
          <Icon type="close" />
        </button>

button 的默认 typesubmit,如果不指定 type,可能会导致不可预期的行为,比如页面刷新等。

建议:error,数量:3

  1. default-props-match-prop-types 默认属性并不在 propTypes 中
static defaultProps = {
    loading: false,
    ghost: false,
    block: false,
  };

  static propTypes = {
    type: PropTypes.string,
    shape: PropTypes.oneOf(ButtonShapes),
    size: PropTypes.oneOf(ButtonSizes),
    htmlType: PropTypes.oneOf(ButtonHTMLTypes),
    onClick: PropTypes.func,
    loading: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
    className: PropTypes.string,
    icon: PropTypes.string,
    block: PropTypes.bool,
  };

首先可能是遗漏了,但是既然使用了 TS,propTypes 是否该去掉了?

建议:off,数量:14

  1. react/destructuring-assignment 使用解构赋值,类似 prefer-destructuring
 if (this.props.listType !== 'picture' && this.props.listType !== 'picture-card') {
      return;
    }

有点严格了,并且 ant desgin 中使用较多,建议关闭。

建议: off ,数量:292

  1. react/jsx-closing-bracket-location 自闭合括号位置

  2. react/jsx-closing-tag-location 括号位置

建议:error,可自动修复

  1. react/jsx-curly-brace-presence 不必要的花括号
const closeIcon = (
      <span className={`${prefixCls}-close-x`}>
        <Icon className={`${prefixCls}-close-icon`} type={'close'} />
      </span>
    );

type 是字符串,不需要花括号。

建议:error,数量:2,可自动修复

  1. react/jsx-indent 缩进

  2. [react/jsx-indent-props] 属性缩进

建议:error,可自动修复

  1. jsx-no-bind 禁止使用 bind
<Dialog
      prefixCls={prefixCls}
      className={classString}
      wrapClassName={classNames({ [`${contentPrefixCls}-centered`]: !!props.centered })}
      onCancel={close.bind(this, { triggerCancel: true })}
      visible={visible}
			...
    >
  ...
</Dialog>

bind 每次 render 都会产生一个新的 function,会有不必要的重新 render,导致性能问题。可以在构造函数中 bind 或使用 decorator

建议:error,数量:1

  1. react/no-access-state-in-setstate 禁止在 setState 中使用 this.state
belowShowChange = () => {
    this.setState({ belowShow: !this.state.belowShow });
  };

因为存在批量更新,如果多次调用,this.state 拿到的数据可能有问题,可以通过回调解决。

建议:error,数量:3

  1. react/no-array-index-key 禁止使用 index 作为子组件的 key
const rowList = [...Array(rows)].map((_, index) => (
      <li key={index} style={{ width: this.getWidth(index) }} />
    ));

首先本身会导致 react warning,同时,使用一个不唯一的 key 可能导致不必要的 render

建议:error,数量:6

  1. react/no-children-prop 不要讲 children 作为属性传递。
let currentContent = content;

  function wrap(needed: boolean | undefined, tag: string) {
    if (!needed) return;

    currentContent = React.createElement(tag, {
      children: currentContent,
    });
  }

可以改写为:

currentContent = React.createElement(tag, currentContent);

建议:error,数量:1

  1. react/no-did-update-set-state 不要在 componentDidUpdate 中使用 setState
componentDidUpdate(prevProps: ButtonProps) {
		...
    const { loading } = this.props;
    if (loading && typeof loading !== 'boolean' && loading.delay) {
      this.delayTimeout = window.setTimeout(() => this.setState({ loading }), loading.delay);
    } else if (prevProps.loading === this.props.loading) {
      return;
    } else {
      this.setState({ loading });
    }
  }

componentDidUpdate 中使用 setState,会马上触发第二次 render,可能导致页面渲染问题?

建议:error,数量:2

  1. react/no-find-dom-node 不要使用 findDOMNode
componentDidMount() {
    const NO_FLEX = ' no-flex';
    const tabNode = ReactDOM.findDOMNode(this) as Element;
    if (tabNode && !isFlexSupported && tabNode.className.indexOf(NO_FLEX) === -1) {
      tabNode.className += NO_FLEX;
    }
  }

findDOMNode 已经过期,可以使用 ref 代替

建议:error,数量:15

  1. react/no-multi-comp 不要在一个文件中定义多个组件

为了提高可读性和可复用性,建议一个文件一个组件。

建议: error,数量:1

  1. react/no-unused-prop-types 不要有未使用的 propTypes

定义的 propTypes ,组件中并未用到。

建议: error,数量:2

  1. react/require-default-props 非必须的属性必须定义在 defaultProps
static defaultProps = {
    dataSource: [],
    render: noop as TransferRender,
    locale: {},
    showSearch: false,
  };

  static propTypes = {
    prefixCls: PropTypes.string,
    disabled: PropTypes.bool,
    ...
 }

问题太多,并且已使用 TS, 建议忽略。

建议:off,数量:140

  1. react/sort-comp 组件内方法需要排序

建议:off,数量:74,可自动修复

  1. spaced-comment 注释符号与内容之间需要空格
/** 是否支持选中 */
checkable?: boolean;

这里正确的单行注释应该是一个星号

建议:error,数量:21,可自动修复


  1. @typescript-eslint/array-type 数组类型
export interface UploadChangeParam {
  file: UploadFile;
  fileList: Array<UploadFile>;
  event?: { percent: number };
}

推荐使用简写 UploadFile[]

建议:error,数量:55,可自动修复

  1. @typescript-eslint/ban-types 禁止一些类型,如 ObjectString
export interface UploadListProps {
  progressAttr?: Object;
}

不使用 Object, 使用 Record<string, any>

建议:error,数量:33,可自动修复

  1. @typescript-eslint/camelcase 驼峰命名
import zh_CN from '../../date-picker/locale/zh_CN';

由于大量存在这种,所以忽略该规则吧

建议:off,数量:90

  1. @typescript-eslint/explicit-member-accessibility 类方法需要访问类型修饰符

需要 private,public 等,感觉不需要,忽略

建议:off,数量:1035

  1. @typescript-eslint/interface-name-prefix interface 前缀

之前内部讨论过,不加I,@边柳

建议:never,数量:1

  1. @typescript-eslint/no-empty-interface 不能有空的接口
interface ParagraphProps extends BlockProps {}

antd design 的应用中,有时需要 extends 一个空接口,所以需要有条件的忽略。

建议:['error', { allowSingleExtends: true }]

  1. @typescript-eslint/no-inferrable-types 不要显式的写出可推断的类型
let id: number = 0;

数字,字符串,布尔值等都是可以推断的类型,不需要写出来。

建议:error,数量:1

  1. @typescript-eslint/no-non-null-assertion 不使用非空断言操作符
if ('openKeys' in nextProps) {
      this.setState({ openKeys: nextProps.openKeys! });
      return;
    }

这个 @边柳 @陈帅 @豆酱 来建议

建议: ?,数量:42

  1. @typescript-eslint/no-object-literal-type-assertion 禁用 as ?
const state = {} as WeekPickerState;

建议是 const state: WeekPickerState = {}; ?

建议:?,数量:9

  1. @typescript-eslint/no-use-before-define 使用在定义之前

在 es6 中不建议这样做

建议: error,数量7

  1. @typescript-eslint/prefer-interface 偏好使用 interface
export type ValidationRule = {
  /** validation error message */
  message?: React.ReactNode;
  /** built-in validation type, available options: https://github.com/yiminghe/async-validator#type */
  type?: string;
  /** indicates whether field is required */
  required?: boolean;
  /** treat required fields that only contain whitespace as errors */
  whitespace?: boolean;
 }

interface 可以被继承合并等

建议:error,数量:8

@clock157
Copy link
Author

clock157 commented Mar 8, 2019

先整理 20个,持续整理。

@ztplz
Copy link
Contributor

ztplz commented Mar 8, 2019

image

const res: RangePickerValue = [start, newEnd];
return res;

@clock157
Copy link
Author

clock157 commented Mar 17, 2019

针对 ant design 的错误,相关规则注释已全部列出。

问题原因

出现这些问题的原因是,之前的 tslinteslint 规则未打通,所以没有检测出来,现在规则已通用,其中大部分的确是应该修复的,那种数量很多的反而不需要修复。

如何做

大家可以看一下,如果没有异议,我会将需要修复的错误分成大概5份,大家认领修复。待议

其他

定下来的规则,可以下沉到 eslint-config-umi 中供其他项目使用,并且 ant-design.eslintrc 不会太难看。

@ztplz
Copy link
Contributor

ztplz commented Mar 17, 2019

image
可以有啊 用它的时候 把这条规则在那个文件里disabled

@ztplz
Copy link
Contributor

ztplz commented Mar 17, 2019

image
其实我们很多时候没遵循一些通用的面向对象语言的规范
像内部私有属性 一般前面加 _
默认public的 加 private protected就行了

@ztplz
Copy link
Contributor

ztplz commented Mar 17, 2019

image
这个可以约束 滥用断言的情况很多
很多时候 定义个变量都要给你来个断言 比如
let x = xx as xxx;

@ztplz
Copy link
Contributor

ztplz commented Mar 17, 2019

image
可有可不有 如果不用这个非空断言 就要加很多if帮助判断

@ztplz
Copy link
Contributor

ztplz commented Mar 17, 2019

image
其实很多情况下是为了省个参数或代码, 而且这个在其他ts项目里是不禁的
let id = 0;
myFunc(++id);
就像例子里的一样 这个myId的变量就是多余的 return ++id 就行了

@DiamondYuan
Copy link
Contributor

阿里可以维护一个开源项目通用的规则仓库

@clock157
Copy link
Author

image
可以有啊 用它的时候 把这条规则在那个文件里disabled

90 个,每个地方都这样写太多了

@clock157
Copy link
Author

阿里可以维护一个开源项目通用的规则仓库

蚂蚁现在维护的:
前端 eslint-config-umi
后端 eslint-config-egg

@ztplz
Copy link
Contributor

ztplz commented Mar 18, 2019

image
现在有个问题 因为我们属性基本都是可选的 但是很多我们都设置了defaultProps
所以某个属性是肯定存在的 但是ts不知道 会类型不符 我们要帮助ts判断
但是如果你用if的话 感觉就没必要 因为defaultProps里我们已经设置了 然后再if判断一次

@afc163
Copy link
Member

afc163 commented Aug 6, 2019

#18051

@afc163 afc163 closed this Aug 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants