如何避免TypeScript类型定义触发ESLint错误及本地与CI差异
问题描述
GitHub Actions工作流配置
name: Build and deploy on: push: branches: - '**' env: app_name: support_case_ui bucket_name_dev: support-ui-static-files-dev bucket_name_prod: support-ui-static-files-prod IS_FEATURE: ${{ github.ref != 'refs/heads/release' && github.ref != 'refs/heads/main'}} IS_DEV: ${{ github.ref == 'refs/heads/main' }} NPM_TOKEN: ${{ secrets.READER_TOKEN }} jobs: build: name: Build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20.x - uses: actions/cache@v4 id: yarn-cache with: path: .yarn/cache key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} restore-keys: | ${{ runner.os }}-yarn- - name: Set environment variables for frontend build # Use environment variables from feature just for the build to go green. Using actual env variables in deploy step run: cat env/.env.dev >> $GITHUB_ENV - name: Install yarn dependencies run: yarn --immutable - name: Check lint run: yarn lint - name: Run tests and build run: yarn test && yarn build deploy-to-feature: name: Deploy to feature runs-on: ubuntu-latest needs: build if: github.ref != 'refs/heads/main' steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20.x - uses: actions/cache@v4 id: yarn-cache with: path: .yarn/cache key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} restore-keys: | ${{ runner.os }}-yarn- - name: Install yarn dependencies run: yarn --immutable - name: Set environment variables for build run: cat env/.env.dev >> $GITHUB_ENV - name: Build app run: yarn build - name: Login GCP dev uses: google-github-actions/auth@v1 with: credentials_json: ${{ secrets.GCP_SERVICEUSER_KEY_DEV }} - name: Set up Cloud SDK uses: google-github-actions/setup-gcloud@v1 - name: Upload static files to feature GCP bucket run: gsutil -m rsync -R -d dist gs://${{env.bucket_name_dev}}/${{env.app_name}}/feature/static deploy-to-main: name: Deploy to main runs-on: ubuntu-latest needs: build steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20.x - uses: actions/cache@v4 id: yarn-cache with: path: .yarn/cache key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} restore-keys: | ${{ runner.os }}-yarn- - name: Install yarn dependencies run: yarn --immutable - name: Set environment variables for build run: cat env/.env.main >> $GITHUB_ENV - name: Build app run: yarn build - name: Login GCP dev uses: google-github-actions/auth@v1 with: credentials_json: ${{ secrets.GCP_SERVICEUSER_KEY_DEV }} - name: Set up Cloud SDK uses: google-github-actions/setup-gcloud@v1 - name: Upload static files to dev GCP bucket run: gsutil -m rsync -R -d dist gs://${{env.bucket_name_dev}}/${{env.app_name}}/main/static deploy-to-prod: name: Deploy to prod runs-on: ubuntu-latest needs: build if: github.ref == 'refs/heads/main' steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20.x - uses: actions/cache@v4 id: yarn-cache with: path: .yarn/cache key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} restore-keys: | ${{ runner.os }}-yarn- - name: Install yarn dependencies run: yarn --immutable - name: Set environment variables for build run: cat env/.env.prod >> $GITHUB_ENV - name: Build app run: yarn build - name: Login GCP dev uses: google-github-actions/auth@v1 with: credentials_json: ${{ secrets.GCP_SERVICEUSER_KEY_PROD }} - name: Set up Cloud SDK uses: google-github-actions/setup-gcloud@v1 - name: Upload static files to prod GCP bucket run: gsutil -m rsync -R -d dist gs://${{env.bucket_name_prod}}/${{env.app_name}}/static
触发错误的TypeScript类型定义
type STEPSTYPE = { [key in Stepper]: number } | { [key in CaseStepper]: number };
CI与本地执行结果差异
CI执行报错
Error: 52:86 error 'key' is defined but never used @typescript-eslint/no-unused-vars
本地执行结果
yarn run v1.22.19 $ eslint ./src/**/*.{js,ts,tsx} package.json --quiet ✨ Done in 3.76s.
当前ESLint配置
module.exports = { parser: "@typescript-eslint/parser", // Specifies the ESLint parser parserOptions: { ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features sourceType: "module", // Allows for the use of imports ecmaFeatures: { jsx: true, // Allows for the parsing of JSX }, }, settings: { react: { version: "detect", // Tells eslint-plugin-react to automatically detect the version of React to use }, "json/sort-package-json": ["name", "version", "private", "scripts", "dependencies", "devDependencies"], }, plugins: ["@typescript-eslint", "prettier", "json-format", "simple-import-sort", "unused-imports"], extends: [ "eslint:recommended", "plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended", ], rules: { "sort-imports": "off", "@typescript-eslint/no-namespace": "off", "@typescript-eslint/ban-ts-comment": "off", "simple-import-sort/imports": "error", "simple-import-sort/exports": "error", "no-unused-vars": "off", "unused-imports/no-unused-imports": "error", "@typescript-eslint/no-var-requires": "warn", "@typescript-eslint/no-empty-function": "warn", "@typescript-eslint/ban-types": "warn", "unused-imports/no-unused-vars": [ "warn", { vars: "all", varsIgnorePattern: "^_", args: "after-used", argsIgnorePattern: "^_" }, ], eqeqeq: ["error", "smart"], }, overrides: [ { files: ["*.js"], rules: { "no-undef": "off", }, }, ], };
需求
- 保留对未使用变量的错误检查,但排除TypeScript类型定义触发的此类错误,不直接禁用
no-unused-vars相关规则; - 解决本地与GitHub Actions工作流执行结果不一致的问题。
解决方案
1. 调整ESLint规则,忽略类型定义中的未使用变量
当前配置中,plugin:@typescript-eslint/recommended规则集默认启用了@typescript-eslint/no-unused-vars为错误级别,而你仅关闭了原生ESLint的no-unused-vars,同时使用了unused-imports插件的规则,导致规则重复且冲突。
方案一:统一使用@typescript-eslint/no-unused-vars并配置忽略类型变量
修改ESLint配置的rules部分,添加以下配置:
"@typescript-eslint/no-unused-vars": [ "error", { // 忽略类型定义中的未使用变量 "ignoreTypeVars": true, // 忽略以下划线开头的变量(可选,保持原有习惯) "varsIgnorePattern": "^_", "argsIgnorePattern": "^_" } ], // 关闭unused-imports的同名规则避免冲突 "unused-imports/no-unused-vars": "off"
方案二:继续使用unused-imports插件并关闭@typescript-eslint/no-unused-vars
若希望保留unused-imports插件的功能,只需关闭@typescript-eslint/no-unused-vars规则:
"@typescript-eslint/no-unused-vars": "off"
注意:unused-imports/no-unused-vars本身会忽略类型定义中的未使用变量,若仍出现问题,需检查该插件的版本是否为最新,或在配置中明确添加ignoreTypeVars: true(部分版本需显式配置)。
2. 解决本地与CI执行结果不一致问题
统一依赖版本
- 确保
yarn.lock文件已提交到仓库,CI中使用yarn --immutable能保证依赖版本与本地完全一致; - 在GitHub Actions的
setup-node步骤中指定与本地相同的yarn版本,避免默认版本差异:
- uses: actions/setup-node@v4 with: node-version: 20.x yarn-version: 1.22.19 # 与本地yarn版本一致
验证缓存与依赖
- 检查CI中的缓存步骤是否正确命中,若缓存异常,可临时禁用缓存重新执行工作流;
- 在CI中添加打印依赖版本的步骤,与本地对比确认一致:
- name: Check dependency versions run: yarn list eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser unused-imports
内容的提问来源于stack exchange,提问作者Leff
相关产品推荐
相关产品推荐

