eslint

这是个代码风格统一的问题,不是语法对错。你们项目用的是 @antfu/eslint-config(Anthony Fu 的配置),它默认要求:模块顶层导出的函数用 function 声明,箭头函数留给回调和局部场景。

为什么 ESLint 要区分两种写法?

核心目的就三个:

  1. 风格统一 --- 全项目一种写法,读代码不用猜「这里为什么用箭头、那里为什么用 function」
  2. 可读性 --- 顶层 export function encrypt() 一眼能看出是模块对外 API;const encrypt = () => {} 更像变量赋值
  3. 减少无意义的差异 --- 两种写法在顶层功能上几乎一样,团队约定一种,避免 PR 里来回改风格

Antfu 的配置哲学是:顶层用 function,箭头函数留给它真正擅长的场景。

什么时候用 function

模块顶层(文件最外层、要 export 的函数):

// ✅ 你们项目的写法

export function encrypt(txt: string) { ... }

export function useProjectList() { ... }

function generateRandomString() { ... } // 文件内私有辅助函数

你们项目里 authApi.tsprojectApi.tscrypto.tsuseProjectList.ts 都是这个模式。

函数/composable 内部的具名函数(Antfu 也倾向用 function):

javascript 复制代码
export function useProjectList() {
  async function fetchList() { ... }   // ✅
  function handleSearch() { ... }      // ✅
}

什么时候用 const xxx = () => {}() => {}

箭头函数更适合这些场景:

1. 回调(最常见)

javascript 复制代码
list.map((item) => item.id)
list.filter(item => item.active)
button.addEventListener('click', () => { ... })

你们项目里就有:

typescript 复制代码
  return raw.map((item) => {
    const row = item as Record<string, unknown>
    // ...
  }).filter(item => Number.isFinite(item.id))

2. 需要保留外层 this

ini 复制代码
// 类或 Options API 里
someObj.onClick = () => {
  this.value = 1  // 箭头函数继承外层的 this
}

3. 单行、临时、不需要名字的函数

scss 复制代码
const double = (n: number) => n * 2
setTimeout(() => doSomething(), 1000)

4. 需要把函数当值传递、且不想提升(hoist)时

javascript 复制代码
const handlers = {
  click: () => { ... },
  submit: () => { ... },
}

快速对照

场景 推荐写法
模块顶层 export 的函数 export function foo() {}
文件内顶层辅助函数 function helper() {}
composable 内部的具名方法 function fetchList() {}
.map / .filter / 事件回调 () => {}
需要固定 this () => {}
对象字面量里的方法(看团队约定) 两种都有人用,你们项目顶层偏 function

总结

ESLint 不是在说「箭头函数不好」,而是在说:顶层导出的函数请用 function,别用 const xxx = () => {}

const xxx = () => {} 依然很好用,只是更适合回调、闭包、需要 lexical this、匿名小函数这类场景,而不是模块的主要 API 定义。

如果不想遵守这条规则,可以在 eslint.config.js 里关掉 antfu/top-level-function(或对应规则),但和你们现有代码风格会不一致。

相关推荐
用户2930750976694 小时前
TypeScript 必考题:Type 与 Interface 全面对比
前端
hunterandroid4 小时前
[鸿蒙从零到一] HarmonyOS 媒体能力实战:图片、音频与视频处理
前端
打呵欠的猫4 小时前
我让 AI 封装了一个 ImageUpload 组件,它设计的 5 层校验链路比我想的周全
前端·ai编程
AlexMaybeBot4 小时前
躺在沙发上开发 Openclaw 的移动端APP
前端·flutter
用户2181697049304 小时前
Flutter(十三)Text Image TextField
前端
程序员黑豆4 小时前
深入解析Java数据类型:基本类型与引用类型的本质区别与实战选择
前端·ai编程·全栈
Wang's Blog5 小时前
AI Agent白手起家60: 多智能体架构解析与 LangGraph 入门
人工智能·架构·wpf
东方小月5 小时前
从零开发一个 Coding Agent(七):实现纯文本 Agent Loop
前端·人工智能
大家的林语冰5 小时前
👉 尤雨溪再次成立新公司,同时官宣 Pinia 4 正式发布!
前端·javascript·vue.js
浮生望5 小时前
React useRef 深度解析:从DOM操作到Web Worker多线程协作
前端