@fast-china/eslint-config 2.1.5 → 2.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +9 -1
  3. package/README.zh.md +9 -1
  4. package/dist/configs/angular.d.mts +2 -3
  5. package/dist/configs/common.d.mts +1 -2
  6. package/dist/configs/environment.d.mts +4 -5
  7. package/dist/configs/ignores.d.mts +3 -4
  8. package/dist/configs/import.d.mts +1 -2
  9. package/dist/configs/javascript.d.mts +1 -2
  10. package/dist/configs/json.d.mts +1 -2
  11. package/dist/configs/lodash.d.mts +2 -3
  12. package/dist/configs/markdown.d.mts +1 -2
  13. package/dist/configs/prettier.d.mts +1 -2
  14. package/dist/configs/prettier.mjs +1 -0
  15. package/dist/configs/prettier.mjs.map +1 -1
  16. package/dist/configs/react.d.mts +2 -3
  17. package/dist/configs/regexp.d.mts +1 -2
  18. package/dist/configs/sort-package.d.mts +1 -2
  19. package/dist/configs/sort-tsconfig.d.mts +1 -2
  20. package/dist/configs/typescript.d.mts +5 -6
  21. package/dist/configs/typescript.mjs +8 -3
  22. package/dist/configs/typescript.mjs.map +1 -1
  23. package/dist/configs/uniapp.d.mts +1 -2
  24. package/dist/configs/vue.d.mts +1 -2
  25. package/dist/configs/vue.mjs +8 -1
  26. package/dist/configs/vue.mjs.map +1 -1
  27. package/dist/constants/index.d.mts +17 -18
  28. package/dist/index.d.mts +6 -6
  29. package/dist/index.mjs +1 -1
  30. package/dist/index.mjs.map +1 -1
  31. package/dist/plugins/import.mjs +0 -1
  32. package/dist/plugins/import.mjs.map +1 -1
  33. package/dist/rules/angular.d.mts +3 -4
  34. package/dist/rules/common.d.mts +8 -5
  35. package/dist/rules/common.mjs +11 -1
  36. package/dist/rules/common.mjs.map +1 -1
  37. package/dist/rules/import.d.mts +1 -2
  38. package/dist/rules/javascript.d.mts +1 -2
  39. package/dist/rules/lodash.d.mts +2 -3
  40. package/dist/rules/react.d.mts +1 -2
  41. package/dist/rules/regexp.d.mts +1 -2
  42. package/dist/rules/sort-package.d.mts +1 -2
  43. package/dist/rules/sort-tsconfig.d.mts +1 -2
  44. package/dist/rules/typescript.d.mts +37 -7
  45. package/dist/rules/typescript.mjs +31 -6
  46. package/dist/rules/typescript.mjs.map +1 -1
  47. package/dist/rules/vue.d.mts +3 -2
  48. package/dist/rules/vue.mjs +2 -0
  49. package/dist/rules/vue.mjs.map +1 -1
  50. package/dist/typegen.d.mts +78 -24
  51. package/docs/engineering-audit.zh.md +2 -2
  52. package/docs/rules-risk.md +27 -17
  53. package/docs/rules-risk.zh.md +17 -7
  54. package/package.json +18 -18
@@ -1,6 +1,6 @@
1
1
  import { Linter } from "eslint";
2
2
  //#region src/typegen.d.ts
3
- interface RuleOptions {
3
+ export interface RuleOptions {
4
4
  /**
5
5
  * Classes decorated with @Component must have suffix "Component" (or custom) in their name. Note: As of v20, this is no longer recommended by the Angular Team.
6
6
  * @see https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/component-class-suffix.md
@@ -50,7 +50,7 @@ interface RuleOptions {
50
50
  * Requires inject() calls to be declared at the top of the class, before any other member
51
51
  * @see https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/inject-at-top.md
52
52
  */
53
- '@angular-eslint/inject-at-top'?: Linter.RuleEntry<[]>;
53
+ '@angular-eslint/inject-at-top'?: Linter.RuleEntry<AngularEslintInjectAtTop>;
54
54
  /**
55
55
  * Angular Lifecycle methods should not be async. Angular does not wait for async lifecycle but the code incorrectly suggests it does.
56
56
  * @see https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-async-lifecycle-method.md
@@ -165,7 +165,7 @@ interface RuleOptions {
165
165
  * Ensures components do not opt out of the default `ChangeDetectionStrategy.OnPush` change detection strategy
166
166
  * @see https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-on-push-component-change-detection.md
167
167
  */
168
- '@angular-eslint/prefer-on-push-component-change-detection'?: Linter.RuleEntry<[]>;
168
+ '@angular-eslint/prefer-on-push-component-change-detection'?: Linter.RuleEntry<AngularEslintPreferOnPushComponentChangeDetection>;
169
169
  /**
170
170
  * Use `OutputEmitterRef` instead of `@Output()`
171
171
  * @see https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-output-emitter-ref.md
@@ -185,7 +185,7 @@ interface RuleOptions {
185
185
  * Use `model` instead of `input` and `output` for two-way bindings
186
186
  * @see https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-signal-model.md
187
187
  */
188
- '@angular-eslint/prefer-signal-model'?: Linter.RuleEntry<[]>;
188
+ '@angular-eslint/prefer-signal-model'?: Linter.RuleEntry<AngularEslintPreferSignalModel>;
189
189
  /**
190
190
  * Use readonly signals instead of `@Input()`, `@ViewChild()` and other legacy decorators
191
191
  * @see https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-signals.md
@@ -196,6 +196,11 @@ interface RuleOptions {
196
196
  * @see https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-standalone.md
197
197
  */
198
198
  '@angular-eslint/prefer-standalone'?: Linter.RuleEntry<[]>;
199
+ /**
200
+ * Ensures that reactive contexts such as computed(), linkedSignal() and effect() read at least one reactive value (a signal). A reactive context with no reactive dependencies never re-runs, which is almost always a mistake.
201
+ * @see https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/reactive-context-must-read-signal.md
202
+ */
203
+ '@angular-eslint/reactive-context-must-read-signal'?: Linter.RuleEntry<AngularEslintReactiveContextMustReadSignal>;
199
204
  /**
200
205
  * The ./ and ../ prefix is standard syntax for relative URLs; don't depend on Angular's current ability to do without that prefix.
201
206
  * @see https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/relative-url-prefix.md
@@ -217,7 +222,7 @@ interface RuleOptions {
217
222
  */
218
223
  '@angular-eslint/runtime-localize'?: Linter.RuleEntry<[]>;
219
224
  /**
220
- * Ensures that keys in type decorators (Component, Directive, NgModule, Pipe) are sorted in a consistent order
225
+ * Ensures that keys in type decorators (Component, Directive, Injectable, NgModule, Pipe) are sorted in a consistent order
221
226
  * @see https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/sort-keys-in-type-decorator.md
222
227
  */
223
228
  '@angular-eslint/sort-keys-in-type-decorator'?: Linter.RuleEntry<AngularEslintSortKeysInTypeDecorator>;
@@ -401,6 +406,11 @@ interface RuleOptions {
401
406
  * @see https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/prefer-static-string-properties.md
402
407
  */
403
408
  '@angular-eslint/template/prefer-static-string-properties'?: Linter.RuleEntry<AngularEslintTemplatePreferStaticStringProperties>;
409
+ /**
410
+ * Suggests using [style] bindings over ngStyle where applicable
411
+ * @see https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/prefer-style-binding.md
412
+ */
413
+ '@angular-eslint/template/prefer-style-binding'?: Linter.RuleEntry<[]>;
404
414
  /**
405
415
  * Ensure that template literals are used instead of concatenating strings or expressions.
406
416
  * @see https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/prefer-template-literal.md
@@ -552,7 +562,7 @@ interface RuleOptions {
552
562
  */
553
563
  '@eslint-react/globals'?: Linter.RuleEntry<[]>;
554
564
  /**
555
- * Validates against passing functions that mutate captured local variables into frozen contexts such as JSX props, hook arguments, and hook return values.
565
+ * Validates against mutating props, state, and other immutable values, including through functions passed into frozen contexts such as JSX props, hook arguments, and hook return values.
556
566
  * @see https://eslint-react.xyz/docs/rules/immutability
557
567
  */
558
568
  '@eslint-react/immutability'?: Linter.RuleEntry<[]>;
@@ -907,7 +917,7 @@ interface RuleOptions {
907
917
  */
908
918
  '@eslint-react/x-globals'?: Linter.RuleEntry<[]>;
909
919
  /**
910
- * Validates against passing functions that mutate captured local variables into frozen contexts such as JSX props, hook arguments, and hook return values.
920
+ * Validates against mutating props, state, and other immutable values, including through functions passed into frozen contexts such as JSX props, hook arguments, and hook return values.
911
921
  * @see https://eslint-react.xyz/docs/rules/immutability
912
922
  */
913
923
  '@eslint-react/x-immutability'?: Linter.RuleEntry<[]>;
@@ -1367,6 +1377,11 @@ interface RuleOptions {
1367
1377
  * @see https://typescript-eslint.io/rules/no-for-in-array
1368
1378
  */
1369
1379
  '@typescript-eslint/no-for-in-array'?: Linter.RuleEntry<[]>;
1380
+ /**
1381
+ * Disallow type operations that resolve to the "empty object" type
1382
+ * @see https://typescript-eslint.io/rules/no-generated-empty-object-type
1383
+ */
1384
+ '@typescript-eslint/no-generated-empty-object-type'?: Linter.RuleEntry<[]>;
1370
1385
  /**
1371
1386
  * Disallow the use of `eval()`-like functions
1372
1387
  * @see https://typescript-eslint.io/rules/no-implied-eval
@@ -3499,7 +3514,7 @@ interface RuleOptions {
3499
3514
  * Disallow unmodified loop conditions
3500
3515
  * @see https://eslint.org/docs/latest/rules/no-unmodified-loop-condition
3501
3516
  */
3502
- 'no-unmodified-loop-condition'?: Linter.RuleEntry<[]>;
3517
+ 'no-unmodified-loop-condition'?: Linter.RuleEntry<NoUnmodifiedLoopCondition>;
3503
3518
  /**
3504
3519
  * Disallow ternary operators when simpler alternatives exist
3505
3520
  * @see https://eslint.org/docs/latest/rules/no-unneeded-ternary
@@ -5150,6 +5165,11 @@ interface RuleOptions {
5150
5165
  * @see https://eslint.vuejs.org/rules/no-setup-props-reactivity-loss.html
5151
5166
  */
5152
5167
  'vue/no-setup-props-reactivity-loss'?: Linter.RuleEntry<[]>;
5168
+ /**
5169
+ * disallow the use of event names that collide with native web event names
5170
+ * @see https://eslint.vuejs.org/rules/no-shadow-native-events.html
5171
+ */
5172
+ 'vue/no-shadow-native-events'?: Linter.RuleEntry<[]>;
5153
5173
  /**
5154
5174
  * enforce component's data property to be a function
5155
5175
  * @see https://eslint.vuejs.org/rules/no-shared-component-data.html
@@ -5826,6 +5846,10 @@ type AngularEslintDirectiveSelector = [] | [({
5826
5846
  prefix?: (string | unknown[]);
5827
5847
  style: ("camelCase" | "kebab-case");
5828
5848
  }])];
5849
+ // ----- @angular-eslint/inject-at-top -----
5850
+ type AngularEslintInjectAtTop = [] | [{
5851
+ additionalInjectFunctions?: string[];
5852
+ }];
5829
5853
  // ----- @angular-eslint/no-input-prefix -----
5830
5854
  type AngularEslintNoInputPrefix = [] | [{
5831
5855
  prefixes?: string[];
@@ -5838,6 +5862,14 @@ type AngularEslintNoInputRename = [] | [{
5838
5862
  type AngularEslintPipePrefix = [] | [{
5839
5863
  prefixes?: string[];
5840
5864
  }];
5865
+ // ----- @angular-eslint/prefer-on-push-component-change-detection -----
5866
+ type AngularEslintPreferOnPushComponentChangeDetection = [] | [{
5867
+ allowExplicitOnPush?: boolean;
5868
+ }];
5869
+ // ----- @angular-eslint/prefer-signal-model -----
5870
+ type AngularEslintPreferSignalModel = [] | [{
5871
+ useTypeChecking?: boolean;
5872
+ }];
5841
5873
  // ----- @angular-eslint/prefer-signals -----
5842
5874
  type AngularEslintPreferSignals = [] | [{
5843
5875
  preferReadonlySignalProperties?: boolean;
@@ -5846,6 +5878,10 @@ type AngularEslintPreferSignals = [] | [{
5846
5878
  useTypeChecking?: boolean;
5847
5879
  additionalSignalCreationFunctions?: string[];
5848
5880
  }];
5881
+ // ----- @angular-eslint/reactive-context-must-read-signal -----
5882
+ type AngularEslintReactiveContextMustReadSignal = [] | [{
5883
+ checkResources?: boolean;
5884
+ }];
5849
5885
  // ----- @angular-eslint/require-localize-metadata -----
5850
5886
  type AngularEslintRequireLocalizeMetadata = [] | [{
5851
5887
  requireDescription?: boolean;
@@ -5856,8 +5892,10 @@ type AngularEslintRequireLocalizeMetadata = [] | [{
5856
5892
  type AngularEslintSortKeysInTypeDecorator = [] | [{
5857
5893
  Component?: string[];
5858
5894
  Directive?: string[];
5895
+ Injectable?: string[];
5859
5896
  NgModule?: string[];
5860
5897
  Pipe?: string[];
5898
+ allowUnconfiguredProperties?: boolean;
5861
5899
  }];
5862
5900
  // ----- @angular-eslint/template/attributes-order -----
5863
5901
  type AngularEslintTemplateAttributesOrder = [] | [{
@@ -5871,6 +5909,8 @@ type AngularEslintTemplateButtonHasType = [] | [{
5871
5909
  // ----- @angular-eslint/template/click-events-have-key-events -----
5872
5910
  type AngularEslintTemplateClickEventsHaveKeyEvents = [] | [{
5873
5911
  ignoreWithDirectives?: string[];
5912
+ requireKeyCode?: boolean;
5913
+ allowedKeyCodes?: string[];
5874
5914
  }];
5875
5915
  // ----- @angular-eslint/template/conditional-complexity -----
5876
5916
  type AngularEslintTemplateConditionalComplexity = [] | [{
@@ -5929,8 +5969,8 @@ type AngularEslintTemplateNoDuplicateAttributes = [] | [{
5929
5969
  }];
5930
5970
  // ----- @angular-eslint/template/no-inline-styles -----
5931
5971
  type AngularEslintTemplateNoInlineStyles = [] | [{
5932
- allowNgStyle?: boolean;
5933
- allowBindToStyle?: boolean;
5972
+ allowNgStyle?: (boolean | "dynamic");
5973
+ allowBindToStyle?: (boolean | "dynamic");
5934
5974
  }];
5935
5975
  // ----- @angular-eslint/template/no-interpolation-in-attributes -----
5936
5976
  type AngularEslintTemplateNoInterpolationInAttributes = [] | [{
@@ -5963,6 +6003,7 @@ type AngularEslintTemplateUseTrackByFunction = [] | [{
5963
6003
  // ----- @angular-eslint/use-injectable-provided-in -----
5964
6004
  type AngularEslintUseInjectableProvidedIn = [] | [{
5965
6005
  ignoreClassNamePattern?: string;
6006
+ allowProvidedInNull?: boolean;
5966
6007
  }];
5967
6008
  // ----- @eslint-react/dom-no-unknown-property -----
5968
6009
  type EslintReactDomNoUnknownProperty = [] | [{
@@ -6593,7 +6634,9 @@ type TypescriptEslintNoMeaninglessVoidOperator = [] | [{
6593
6634
  }];
6594
6635
  // ----- @typescript-eslint/no-misused-promises -----
6595
6636
  type TypescriptEslintNoMisusedPromises = [] | [{
6596
- checksConditionals?: boolean;
6637
+ checksConditionals?: (boolean | {
6638
+ flagUnions?: ("all" | "strict" | "none");
6639
+ });
6597
6640
  checksSpreads?: boolean;
6598
6641
  checksVoidReturn?: (boolean | {
6599
6642
  arguments?: boolean;
@@ -7745,15 +7788,19 @@ type JsoncSortKeys = ([{
7745
7788
  hasProperties?: string[];
7746
7789
  order: ((string | {
7747
7790
  keyPattern?: string;
7748
- order?: {
7791
+ order?: ({
7749
7792
  type?: ("asc" | "desc");
7750
7793
  caseSensitive?: boolean;
7751
7794
  natural?: boolean;
7752
- };
7795
+ } | {
7796
+ type: "ignore";
7797
+ });
7753
7798
  })[] | {
7754
7799
  type?: ("asc" | "desc");
7755
7800
  caseSensitive?: boolean;
7756
7801
  natural?: boolean;
7802
+ } | {
7803
+ type: "ignore";
7757
7804
  });
7758
7805
  minKeys?: number;
7759
7806
  allowLineSeparatedGroups?: boolean;
@@ -7762,15 +7809,19 @@ type JsoncSortKeys = ([{
7762
7809
  hasProperties?: string[];
7763
7810
  order: ((string | {
7764
7811
  keyPattern?: string;
7765
- order?: {
7812
+ order?: ({
7766
7813
  type?: ("asc" | "desc");
7767
7814
  caseSensitive?: boolean;
7768
7815
  natural?: boolean;
7769
- };
7816
+ } | {
7817
+ type: "ignore";
7818
+ });
7770
7819
  })[] | {
7771
7820
  type?: ("asc" | "desc");
7772
7821
  caseSensitive?: boolean;
7773
7822
  natural?: boolean;
7823
+ } | {
7824
+ type: "ignore";
7774
7825
  });
7775
7826
  minKeys?: number;
7776
7827
  allowLineSeparatedGroups?: boolean;
@@ -8694,6 +8745,10 @@ type NoUnderscoreDangle = [] | [{
8694
8745
  allowInArrayDestructuring?: boolean;
8695
8746
  allowInObjectDestructuring?: boolean;
8696
8747
  }];
8748
+ // ----- no-unmodified-loop-condition -----
8749
+ type NoUnmodifiedLoopCondition = [] | [{
8750
+ checkConditionalExpressions?: boolean;
8751
+ }];
8697
8752
  // ----- no-unneeded-ternary -----
8698
8753
  type NoUnneededTernary = [] | [{
8699
8754
  defaultAssignment?: boolean;
@@ -10006,7 +10061,7 @@ type VueNoDeprecatedSlotAttribute = [] | [{
10006
10061
  }];
10007
10062
  // ----- vue/no-dupe-keys -----
10008
10063
  type VueNoDupeKeys = [] | [{
10009
- groups?: unknown[];
10064
+ groups?: string[];
10010
10065
  }];
10011
10066
  // ----- vue/no-duplicate-attr-inheritance -----
10012
10067
  type VueNoDuplicateAttrInheritance = [] | [{
@@ -10129,8 +10184,8 @@ type VueNoReservedComponentNames = [] | [{
10129
10184
  }];
10130
10185
  // ----- vue/no-reserved-keys -----
10131
10186
  type VueNoReservedKeys = [] | [{
10132
- reserved?: unknown[];
10133
- groups?: unknown[];
10187
+ reserved?: string[];
10188
+ groups?: string[];
10134
10189
  }];
10135
10190
  // ----- vue/no-reserved-props -----
10136
10191
  type VueNoReservedProps = [] | [{
@@ -10218,7 +10273,7 @@ type VueNoTemplateTargetBlank = [] | [{
10218
10273
  }];
10219
10274
  // ----- vue/no-undef-components -----
10220
10275
  type VueNoUndefComponents = [] | [{
10221
- ignorePatterns?: unknown[];
10276
+ ignorePatterns?: string[];
10222
10277
  }];
10223
10278
  // ----- vue/no-undef-directives -----
10224
10279
  type VueNoUndefDirectives = [] | [{
@@ -10325,7 +10380,7 @@ type VueOperatorLinebreak = [] | [("after" | "before" | "none" | null)] | [("aft
10325
10380
  }];
10326
10381
  // ----- vue/order-in-components -----
10327
10382
  type VueOrderInComponents = [] | [{
10328
- order?: unknown[];
10383
+ order?: (string | string[])[];
10329
10384
  }];
10330
10385
  // ----- vue/padding-line-between-blocks -----
10331
10386
  type VuePaddingLineBetweenBlocks = [] | [("never" | "always")];
@@ -10414,8 +10469,8 @@ type VueSlotNameCasing = [] | [("camelCase" | "kebab-case" | "singleword")];
10414
10469
  // ----- vue/sort-keys -----
10415
10470
  type VueSortKeys = [] | [("asc" | "desc")] | [("asc" | "desc"), {
10416
10471
  caseSensitive?: boolean;
10417
- ignoreChildrenOf?: unknown[];
10418
- ignoreGrandchildrenOf?: unknown[];
10472
+ ignoreChildrenOf?: string[];
10473
+ ignoreGrandchildrenOf?: string[];
10419
10474
  minKeys?: number;
10420
10475
  natural?: boolean;
10421
10476
  allowLineSeparatedGroups?: boolean;
@@ -10474,7 +10529,7 @@ type VueValidVFor = [] | [{
10474
10529
  }];
10475
10530
  // ----- vue/valid-v-on -----
10476
10531
  type VueValidVOn = [] | [{
10477
- modifiers?: unknown[];
10532
+ modifiers?: string[];
10478
10533
  }];
10479
10534
  // ----- vue/valid-v-slot -----
10480
10535
  type VueValidVSlot = [] | [{
@@ -10495,5 +10550,4 @@ type Yoda = [] | [("always" | "never")] | [("always" | "never"), {
10495
10550
  onlyEquality?: boolean;
10496
10551
  }];
10497
10552
  //#endregion
10498
- export { RuleOptions };
10499
10553
  //# sourceMappingURL=typegen.d.mts.map
@@ -13,7 +13,7 @@
13
13
  - JavaScript、TypeScript、Import 和 RegExp 只有一套共享规则。
14
14
  - `@/**` 根别名归入 internal;类型导入位于所有其他非样式导入之后,并在 type 总分组内按来源层级排序。
15
15
  - 样式导入由独立规则约束为最后一个连续分组,不参与普通 import 字母排序,也不提供自动修复。
16
- - TypeScript、Vue 和 React TypeScript 始终使用 `recommendedTypeChecked` 与 Project Service。
16
+ - TypeScript、Vue 和 React TypeScript 始终使用 `strictTypeChecked`、`stylisticTypeChecked` 与 Project Service。
17
17
  - Vue 使用 `flat/recommended`,并叠加事件声明、kebab-case 属性、闭合标签和排序规则。
18
18
  - RegExp 使用显式审查过的正确性与安全规则,不继承完整偏好型推荐集合。
19
19
  - React 使用 `@eslint-react` 推荐预置和 React 官方 Hooks Recommended,并关闭重复实现。
@@ -38,7 +38,7 @@
38
38
  | ------------- | ---- | -------------------------------------------------- |
39
39
  | 公共 API | 通过 | 根入口固定、其他能力由独立子路径组合 |
40
40
  | JavaScript | 通过 | 核心 recommended + 统一现代语法规则 |
41
- | TypeScript | 通过 | 固定 `recommendedTypeChecked` 与 Project Service |
41
+ | TypeScript | 通过 | 固定严格、风格类型感知预置与 Project Service |
42
42
  | Vue 3 | 通过 | `vue-eslint-parser` + `flat/recommended` |
43
43
  | UniApp | 通过 | 默认 `.nvue`、globals、清单注释和 `unpackage` 忽略 |
44
44
  | React | 通过 | 显式组合 JSX/TSX、Hooks Recommended 与 DOM 安全 |
@@ -1,6 +1,6 @@
1
1
  # Default Rules and Risk Guide
2
2
 
3
- This document describes the current 2.1.5 configuration model, major rules, and migration risks. Source comments explain current intent only; historical changes belong in `CHANGELOG.md`.
3
+ This document describes the current 2.1.7 configuration model, major rules, and migration risks. Source comments explain current intent only; historical changes belong in `CHANGELOG.md`.
4
4
 
5
5
  ## Configuration model
6
6
 
@@ -21,23 +21,25 @@ The root entry is a fixed Vue 3 + TypeScript + UniApp preset:
21
21
 
22
22
  ## Preset sources
23
23
 
24
- | Domain | Preset or implementation |
25
- | ---------- | -------------------------------------------------------------------------- |
26
- | JavaScript | `@eslint/js` recommended plus local rules |
27
- | TypeScript | typescript-eslint `recommendedTypeChecked` plus Project Service |
28
- | Vue | `eslint-plugin-vue` `flat/recommended` plus type-aware TypeScript |
29
- | React | `@eslint-react` recommended/type-checked plus React Hooks Flat Recommended |
30
- | Angular | Angular ESLint TypeScript, template, and accessibility recommended presets |
31
- | JSON | `eslint-plugin-jsonc` recommended presets for three dialects |
32
- | Import | `eslint-plugin-import-x` recommended plus a fixed ordering policy |
33
- | RegExp | Explicit correctness, safety, and super-linear backtracking rules |
34
- | Prettier | `eslint-config-prettier` conflict disabling |
24
+ | Domain | Preset or implementation |
25
+ | ---------- | ----------------------------------------------------------------------------- |
26
+ | JavaScript | `@eslint/js` recommended plus local rules |
27
+ | TypeScript | typescript-eslint strict and stylistic type-checked presets + Project Service |
28
+ | Vue | `eslint-plugin-vue` `flat/recommended` plus type-aware TypeScript |
29
+ | React | `@eslint-react` recommended/type-checked plus React Hooks Flat Recommended |
30
+ | Angular | Angular ESLint TypeScript, template, and accessibility recommended presets |
31
+ | JSON | `eslint-plugin-jsonc` recommended presets for three dialects |
32
+ | Import | `eslint-plugin-import-x` recommended plus a fixed ordering policy |
33
+ | RegExp | Explicit correctness, safety, and super-linear backtracking rules |
34
+ | Prettier | `eslint-config-prettier` conflict disabling |
35
35
 
36
36
  ## Major rules
37
37
 
38
38
  ### JavaScript
39
39
 
40
- - `camelcase: ["error", { properties: "never" }]`
40
+ - `camelcase: ["error", { properties: "never" }]` requires camelCase variables and types while preserving external protocol property names.
41
+ - `no-empty` allows intentionally empty catches and still reports other empty blocks.
42
+ - `no-eval` and `no-void` are errors; `curly: ["error", "multi-line", "consistent"]` applies, and an existing `default` branch must come last.
41
43
  - `no-debugger: "error"`
42
44
  - `no-use-before-define` warns; classes and variables must be declared first while function declarations may be hoisted.
43
45
  - `prefer-arrow-callback`, `logical-assignment-operators`, and `prefer-object-spread` are errors.
@@ -48,14 +50,22 @@ The root entry is a fixed Vue 3 + TypeScript + UniApp preset:
48
50
 
49
51
  ### TypeScript
50
52
 
51
- - `recommendedTypeChecked` and `projectService: true` are always enabled; TypeScript, TSX, Vue, and NVue share `extraFileExtensions: [".vue", ".nvue"]` to prevent Project Service reloads during mixed-file linting.
53
+ - `strictTypeChecked`, `stylisticTypeChecked`, and `projectService: true` are always enabled; TypeScript, TSX, Vue, and NVue share `extraFileExtensions: [".vue", ".nvue"]` to prevent Project Service reloads during mixed-file linting.
54
+ - `no-floating-promises` and `strict-void-return` are disabled so Promise waiting follows business semantics; `no-void` rejects `void promise` workarounds. `no-misused-promises`, `await-thenable`, `require-await`, and the unsafe-type rules remain strict, while Promise-returning handlers are allowed in Vue templates and TSX attributes.
55
+ - Named TypeScript and TSX functions require explicit return types, except inline callbacks and already typed function expressions; exported module boundaries still require explicit types.
56
+ - Vue/NVue SFCs disable function-return and module-boundary annotations and unused parameter checks, while unused variables and imports remain errors. Templates do not infer parameter types back into standalone script handlers, so those parameters still require explicit annotations.
52
57
  - `explicit-module-boundary-types` is an error and does not allow explicitly typed `any` arguments as an escape hatch.
53
- - `explicit-function-return-type` is not additionally enabled, so internal functions and callbacks can rely on inference.
54
58
  - `no-explicit-any` warns.
55
- - `no-unused-vars` is an error; an `_` prefix marks intentional omissions and rest siblings are ignored.
59
+ - Regular TS/TSX parameters and caught errors can use an `_` prefix to mark intentional omissions; ordinary variables cannot use that prefix to evade the check.
56
60
  - `no-empty-function` only allows empty constructors and override methods.
57
- - `consistent-type-imports` fixes type-only dependencies as separate `import type` declarations.
61
+ - `consistent-type-imports` fixes type-only dependencies as separate `import type` declarations, and `no-import-type-side-effects` rejects runtime imports containing only inline type specifiers.
58
62
  - `no-non-null-assertion` is an error.
63
+ - `switch-exhaustiveness-check` is an error; `no-deprecated` and `no-unnecessary-condition` warn.
64
+ - Numeric template interpolation and concise void arrow callbacks are allowed; dynamic object deletion and static-only utility classes are not forcibly rewritten.
65
+ - `consistent-type-exports` and `prefer-readonly` are errors; primitive values are not forced from `||` to `??`.
66
+ - `no-eval`, `no-implied-eval`, and `no-new-func` reject direct or indirect dynamic string execution; `no-promise-executor-return` rejects ignored executor returns, and Vue setup props or refs cannot be used in ways that lose reactivity.
67
+ - `unified-signatures` preserves public overloads with different parameter names or standalone JSDoc; the stricter core `no-void` replaces `no-meaningless-void-operator`.
68
+ - `consistent-type-definitions`, `consistent-indexed-object-style`, `class-literal-property-style`, and `prefer-regexp-exec` are disabled as syntax-only preferences.
59
69
 
60
70
  ### Vue
61
71
 
@@ -1,6 +1,6 @@
1
1
  # 默认规则与风险指南
2
2
 
3
- 本文说明 2.1.5 当前配置模型、主要规则和迁移风险。规则源码注释只解释现行意图;历史差异统一记录在 `CHANGELOG.md`。
3
+ 本文说明 2.1.7 当前配置模型、主要规则和迁移风险。规则源码注释只解释现行意图;历史差异统一记录在 `CHANGELOG.md`。
4
4
 
5
5
  ## 配置模型
6
6
 
@@ -24,7 +24,7 @@ SDK、OA、Admin、Vue Web 与 UniApp 客户端共享同一套 JavaScript、Type
24
24
  | 领域 | 预置或实现 |
25
25
  | ---------- | ----------------------------------------------------------------------- |
26
26
  | JavaScript | `@eslint/js` recommended + 本地规则 |
27
- | TypeScript | typescript-eslint `recommendedTypeChecked` + Project Service |
27
+ | TypeScript | typescript-eslint 严格与风格类型感知预置 + Project Service |
28
28
  | Vue | `eslint-plugin-vue` `flat/recommended` + 类型感知 TypeScript |
29
29
  | React | `@eslint-react` recommended/type-checked + React Hooks Flat Recommended |
30
30
  | Angular | Angular ESLint TypeScript、模板及无障碍 recommended |
@@ -37,7 +37,9 @@ SDK、OA、Admin、Vue Web 与 UniApp 客户端共享同一套 JavaScript、Type
37
37
 
38
38
  ### JavaScript
39
39
 
40
- - `camelcase: ["error", { properties: "never" }]`
40
+ - `camelcase: ["error", { properties: "never" }]`:变量和类型使用 camelCase,对象属性允许沿用外部协议字段名。
41
+ - `no-empty` 允许明确忽略失败的空 catch,其他空代码块仍报错。
42
+ - `no-eval` 与 `no-void` 为 `error`;`curly: ["error", "multi-line", "consistent"]`,已有的 `default` 分支必须位于最后。
41
43
  - `no-debugger: "error"`
42
44
  - `no-use-before-define` 为 `warn`;类和变量必须先声明,函数声明允许提升。
43
45
  - `prefer-arrow-callback`、`logical-assignment-operators`、`prefer-object-spread` 为 `error`。
@@ -48,14 +50,22 @@ SDK、OA、Admin、Vue Web 与 UniApp 客户端共享同一套 JavaScript、Type
48
50
 
49
51
  ### TypeScript
50
52
 
51
- - 始终启用 `recommendedTypeChecked` 与 `projectService: true`;TypeScript、TSX、Vue 与 NVue 统一使用 `extraFileExtensions: [".vue", ".nvue"]`,避免混合检查时 Project Service 重载项目。
53
+ - 始终启用 `strictTypeChecked`、`stylisticTypeChecked` 与 `projectService: true`;TypeScript、TSX、Vue 与 NVue 统一使用 `extraFileExtensions: [".vue", ".nvue"]`,避免混合检查时 Project Service 重载项目。
54
+ - `no-floating-promises` 与 `strict-void-return` 关闭,Promise 是否等待由业务语义决定;`no-void` 禁止用 `void promise` 规避检查。`no-misused-promises`、`await-thenable`、`require-await` 和 unsafe 类型规则保持严格,但 Vue 模板与 TSX 属性允许 Promise 返回的事件处理函数。
55
+ - TypeScript 与 TSX 的命名函数要求显式返回类型,内联回调和已有函数类型约束的表达式除外;模块导出边界仍要求显式类型。
56
+ - Vue/NVue SFC 关闭函数返回类型与模块边界类型要求,并关闭形参和 catch 形参的未使用检查;普通未使用变量和导入仍报错。模板不会反向推断独立处理函数的参数类型,这类参数仍需显式标注。
52
57
  - `explicit-module-boundary-types` 为 `error`,模块导出边界必须显式声明类型,不允许用显式 `any` 参数规避。
53
- - `explicit-function-return-type` 不额外启用,内部函数和回调可以依赖推断。
54
58
  - `no-explicit-any` 为 `warn`。
55
- - `no-unused-vars` `error`;`_` 前缀表示有意忽略,rest siblings 不误报。
59
+ - 普通 TS/TSX 的未使用参数和异常可用 `_` 前缀明确忽略;未使用普通变量不能用该前缀规避。
56
60
  - `no-empty-function` 仅允许空构造函数和空覆写方法。
57
- - `consistent-type-imports` 使用独立 `import type` 修复形式。
61
+ - `consistent-type-imports` 使用独立 `import type` 修复形式,`no-import-type-side-effects` 禁止仅含内联类型说明符的运行时导入。
58
62
  - `no-non-null-assertion` 为 `error`。
63
+ - `switch-exhaustiveness-check` 为 `error`;`no-deprecated` 与 `no-unnecessary-condition` 为 `warn`。
64
+ - 模板字符串允许数字插值,箭头简写允许直接返回 void;动态对象字段删除和纯静态工具类不强制改写。
65
+ - `consistent-type-exports` 与 `prefer-readonly` 为 `error`;原始类型不强制将 `||` 改成 `??`。
66
+ - `no-eval`、`no-implied-eval` 与 `no-new-func` 禁止直接或间接动态执行字符串代码;`no-promise-executor-return` 禁止误用 Promise executor 返回值;Vue setup props 和 ref 禁止以丢失响应性的方式使用。
67
+ - `unified-signatures` 保留参数名不同或具有独立 JSDoc 的公共重载;`no-meaningless-void-operator` 由更严格的核心 `no-void` 替代。
68
+ - `consistent-type-definitions`、`consistent-indexed-object-style`、`class-literal-property-style`、`prefer-regexp-exec` 关闭,避免纯语法偏好阻断构建。
59
69
 
60
70
  ### Vue
61
71
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fast-china/eslint-config",
3
- "version": "2.1.5",
3
+ "version": "2.1.7",
4
4
  "description": "Practical, typed ESLint Flat Config for Vue 3, UniApp, React, Angular, Vite, TypeScript, JavaScript, and Node.js.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -91,31 +91,31 @@
91
91
  "typescript": "^6.0.0"
92
92
  },
93
93
  "dependencies": {
94
- "@angular-eslint/eslint-plugin": "^22.1.0",
95
- "@angular-eslint/eslint-plugin-template": "^22.1.0",
96
- "@angular-eslint/template-parser": "^22.1.0",
97
- "@eslint-react/eslint-plugin": "^5.18.1",
98
- "@eslint/js": "^10.0.0",
94
+ "@angular-eslint/eslint-plugin": "^22.5.0",
95
+ "@angular-eslint/eslint-plugin-template": "^22.5.0",
96
+ "@angular-eslint/template-parser": "^22.5.0",
97
+ "@eslint-react/eslint-plugin": "^5.19.0",
98
+ "@eslint/js": "^10.0.1",
99
99
  "@eslint/markdown": "^8.0.3",
100
- "eslint-config-flat-gitignore": "^2.0.0",
101
- "eslint-config-prettier": "^10.0.0",
100
+ "eslint-config-flat-gitignore": "^2.4.0",
101
+ "eslint-config-prettier": "^10.1.8",
102
102
  "eslint-plugin-import-x": "^4.17.1",
103
- "eslint-plugin-jsonc": "^3.3.0",
103
+ "eslint-plugin-jsonc": "^3.4.2",
104
104
  "eslint-plugin-react-hooks": "^7.1.1",
105
- "eslint-plugin-regexp": "^3.1.1",
106
- "eslint-plugin-vue": "^10.10.0",
107
- "globals": "^17.8.0",
108
- "typescript-eslint": "^8.65.0",
105
+ "eslint-plugin-regexp": "^3.3.0",
106
+ "eslint-plugin-vue": "^10.11.0",
107
+ "globals": "^17.12.0",
108
+ "typescript-eslint": "^8.70.0",
109
109
  "vue-eslint-parser": "^10.4.1"
110
110
  },
111
111
  "devDependencies": {
112
- "@eslint/config-inspector": "^3.1.1",
113
- "@types/node": "^24.13.3",
114
- "eslint": "^10.8.0",
112
+ "@eslint/config-inspector": "^3.4.1",
113
+ "@types/node": "^24.13.4",
114
+ "eslint": "^10.10.0",
115
115
  "eslint-typegen": "^2.3.1",
116
116
  "prettier": "^3.9.6",
117
- "tsdown": "^0.22.14",
118
- "tsx": "^4.23.1",
117
+ "tsdown": "^0.23.0",
118
+ "tsx": "^4.23.13",
119
119
  "typescript": "^6.0.3"
120
120
  },
121
121
  "engines": {