You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+TypeScript+Tailwind可复用Button组件适配ESLint问题求助

问题

我是React、TypeScript、Tailwind及ESLint的新手,正在用这些技术构建项目,目前重点学习TypeScript和ESLint。原本创建了一个包含图标和文字的按钮,现在想改成可复用组件,参考过往JS组件经验尝试后没成功。后来参考文章代码实现组件,但粘贴到VSCode后ESLint报错Function component is not a function declaration。查看规则说明修改代码后,又出现Property 'FC' does not exist on type 'typeof React'.ts(2339)、Binding element 'children' implicitly has an 'any' type.ts(7031)等错误,多次调试无果。

组件代码

import React from 'react';

// interface to declare all our prop types
interface Props {
  children: React.ReactNode;
  onClick: () => void;
  variant?: string, // default, primary, info, success, warning, danger, dark
  size?: string, // sm, md, lg
  disabled?: boolean;
}

// button component, consuming props
const Button: React.FC<Props> = ({
  children,
  onClick,
  variant = 'default',
  size = 'md',
  disabled,
  ...rest
}) => {
  return (
    <button
      className={`btn ${variant} ${size}` + (disabled ? ' disabled' : '')}
      onClick={onClick}
      disabled={disabled}
      {...rest}
    >
      {children}
    </button>
  );
};

export default Button;

修改后的错误代码片段

const Button = (React.FC<Props>) => ({

ESLint配置

module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: [
    'airbnb',
    'airbnb/hooks',
    'airbnb-typescript',
    'plugin:react/recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:prettier/recommended',
    'plugin:jsx-a11y/recommended',
    'plugin:tailwindcss/recommended',
  ],
  overrides: [],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
    project: './tsconfig.json',
  },
  plugins: ['react', '@typescript-eslint', 'prettier', 'jsx-a11y', 'tailwindcss'],
  rules: {
    'react/react-in-jsx-scope': 0,
    'react/prop-types': 0,
    'react/require-default-props': 0,
    'max-classes-per-file': 0,
    'tailwindcss/no-custom-classname': 0,
    'react/jsx-props-no-spreading': 0,
    'prettier/prettier': [
      'warn',
      {
        endOfLine: 'crlf',
      },
      {usePrettierrc: true},
    ],
  },
};

解决方案

1. 解决Function component is not a function declaration错误

这个错误来自Airbnb的react/function-component-definition规则,默认要求函数组件使用函数声明形式,而非箭头函数赋值。你有两种解决方式:

方式一:改用函数声明

直接将组件改为函数声明格式,符合Airbnb规则要求:

import React from 'react';

interface Props {
  children: React.ReactNode;
  onClick: () => void;
  variant?: string;
  size?: string;
  disabled?: boolean;
}

// 改用函数声明形式
function Button({
  children,
  onClick,
  variant = 'default',
  size = 'md',
  disabled,
  ...rest
}: Props) {
  return (
    <button
      className={`btn ${variant} ${size}${disabled ? ' disabled' : ''}`}
      onClick={onClick}
      disabled={disabled}
      {...rest}
    >
      {children}
    </button>
  );
}

export default Button;

方式二:调整ESLint规则

如果偏好箭头函数写法,在ESLint配置的rules中添加规则,允许命名组件使用箭头函数:

'react/function-component-definition': [
  2,
  {
    namedComponents: 'arrow-function',
  },
],

2. 解决Property 'FC' does not exist on type 'typeof React'错误

React 18+ 中React.FC不再作为默认导出的一部分,且官方更推荐直接为组件参数指定props类型(无需依赖FC)。如果仍想使用FC,需单独导入:

import React, { FC } from 'react';

// 之后可正常使用FC<Props>
const Button: FC<Props> = ({ ... }) => { ... };

但更推荐的写法是直接给函数参数指定Props类型,如方式一中的代码,无需依赖FC。

3. 解决Binding element 'children' implicitly has an 'any' type错误

你修改后的代码是语法错误,正确的类型标注应该给函数参数指定类型,而非给箭头函数本身套FC类型。示例:

// 正确的箭头函数+类型标注写法
const Button = ({
  children,
  onClick,
  variant = 'default',
  size = 'md',
  disabled,
  ...rest
}: Props) => {
  // 组件逻辑
};

修正后的完整代码(函数声明+严谨类型版)

import React from 'react';

// 用字面量类型替代string,更符合TypeScript严谨性要求
interface Props {
  children: React.ReactNode;
  onClick: () => void;
  variant?: 'default' | 'primary' | 'info' | 'success' | 'warning' | 'danger' | 'dark';
  size?: 'sm' | 'md' | 'lg';
  disabled?: boolean;
}

function Button({
  children,
  onClick,
  variant = 'default',
  size = 'md',
  disabled,
  ...rest
}: Props) {
  return (
    <button
      className={`btn ${variant} ${size}${disabled ? ' disabled' : ''}`}
      onClick={onClick}
      disabled={disabled}
      {...rest}
    >
      {children}
    </button>
  );
}

export default Button;

内容的提问来源于stack exchange,提问作者Projektant42

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 11:39:55