@qlover/create-app 0.10.6 → 0.12.0

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.
@@ -5,6 +5,7 @@ import importPlugin from 'eslint-plugin-import';
5
5
  import prettierPlugin from 'eslint-plugin-prettier';
6
6
  import unusedImports from 'eslint-plugin-unused-imports';
7
7
  import qloverEslint from '@qlover/eslint-plugin';
8
+ import tseslint from 'typescript-eslint';
8
9
 
9
10
  const __filename = fileURLToPath(import.meta.url);
10
11
  const __dirname = dirname(__filename);
@@ -106,7 +107,7 @@ const eslintConfig = [
106
107
  rules: {
107
108
  '@qlover-eslint/ts-class-method-return': 'error',
108
109
  '@qlover-eslint/ts-class-member-accessibility': 'error',
109
- '@qlover-eslint/ts-class-override': 'error',
110
+ '@qlover-eslint/ts-class-override': 'off',
110
111
  '@qlover-eslint/require-root-testid': ['error', {
111
112
  exclude: ['/Provider$/']
112
113
  }],
@@ -188,6 +189,80 @@ const eslintConfig = [
188
189
  'import/no-default-export': 'error',
189
190
  }
190
191
  },
192
+ // TypeScript files with type checking for ts-class-override rule
193
+ // The ts-class-override rule requires full type information to accurately detect:
194
+ // - Methods that override parent class methods (via extends)
195
+ // - Methods that implement interface methods (via implements)
196
+ // Without type checking, the rule falls back to AST-based heuristics which are less accurate
197
+ // This separate config block enables type checking only for TypeScript files to provide
198
+ // accurate override detection while maintaining good performance
199
+ ...tseslint.configs.recommendedTypeChecked.map((config) => ({
200
+ ...config,
201
+ files: ['src/**/*.{ts,tsx}'],
202
+ ignores: [
203
+ '**/dist/**',
204
+ '**/build/**',
205
+ '**/ts-build/**',
206
+ '**/node_modules/**',
207
+ '**/.nx/**',
208
+ '**/.cache/**',
209
+ '**/coverage/**',
210
+ '**/*.d.ts',
211
+ '**/*.config.ts',
212
+ '**/*.test.ts',
213
+ '**/__mocks__/**',
214
+ '**/__tests__/**',
215
+ '**/*.spec.ts',
216
+ ...(config.ignores || [])
217
+ ],
218
+ languageOptions: {
219
+ ...config.languageOptions,
220
+ parserOptions: {
221
+ ...config.languageOptions?.parserOptions,
222
+ project: './tsconfig.json',
223
+ tsconfigRootDir: __dirname
224
+ }
225
+ },
226
+ plugins: {
227
+ ...config.plugins,
228
+ '@qlover-eslint': qloverEslint
229
+ },
230
+ rules: {
231
+ ...config.rules,
232
+ // Enable ts-class-override rule with full type information
233
+ // This rule is disabled in the base config above and only enabled here where
234
+ // type information is available, ensuring accurate detection of override relationships
235
+ '@qlover-eslint/ts-class-override': 'error',
236
+ // Disable other type-checked rules to avoid performance impact
237
+ // We only need type checking for ts-class-override, so we disable other
238
+ // type-aware rules that would slow down linting without providing value
239
+ '@typescript-eslint/ban-ts-comment': 'off',
240
+ '@typescript-eslint/restrict-template-expressions': 'off',
241
+ '@typescript-eslint/no-unsafe-assignment': 'off',
242
+ '@typescript-eslint/no-unnecessary-type-assertion': 'off',
243
+ '@typescript-eslint/no-redundant-type-constituents': 'off',
244
+ '@typescript-eslint/no-unsafe-return': 'off',
245
+ '@typescript-eslint/no-empty-object-type': 'off',
246
+ '@typescript-eslint/no-unsafe-call': 'off',
247
+ '@typescript-eslint/no-unsafe-member-access': 'off',
248
+ '@typescript-eslint/no-unsafe-argument': 'off',
249
+ '@typescript-eslint/no-unsafe-enum-comparison': 'off',
250
+ '@typescript-eslint/no-unsafe-literal-comparison': 'off',
251
+ '@typescript-eslint/no-unsafe-nullish-coalescing': 'off',
252
+ '@typescript-eslint/no-unsafe-optional-chaining': 'off',
253
+ '@typescript-eslint/unbound-method': 'off',
254
+ '@typescript-eslint/await-thenable': 'off',
255
+ '@typescript-eslint/no-floating-promises': 'off',
256
+ '@typescript-eslint/no-misused-promises': 'off',
257
+ '@typescript-eslint/require-await': 'off',
258
+ '@typescript-eslint/no-base-to-string': 'off',
259
+ '@typescript-eslint/prefer-promise-reject-errors': 'off',
260
+ '@typescript-eslint/no-duplicate-type-constituents': 'off',
261
+ // Disable @typescript-eslint/no-unused-vars as we use unused-imports/no-unused-vars instead
262
+ '@typescript-eslint/no-unused-vars': 'off',
263
+ '@typescript-eslint/only-throw-error': 'off'
264
+ }
265
+ })),
191
266
  // 为特定文件允许 default export
192
267
  {
193
268
  files: [
@@ -69,6 +69,7 @@
69
69
  "eslint-plugin-prettier": "^5.5.4",
70
70
  "eslint-plugin-unused-imports": "^4.2.0",
71
71
  "prettier": "^3.6.2",
72
+ "typescript-eslint": "^8.15.0",
72
73
  "tailwindcss": "^4",
73
74
  "typescript": "^5"
74
75
  },
@@ -627,7 +627,20 @@ describe('AsyncService', () => {
627
627
 
628
628
  ### Type Safety Testing
629
629
 
630
+ TypeScript project tests should not only verify runtime behavior but also ensure the correctness of the type system. Vitest provides the `expectTypeOf` utility for compile-time type checking.
631
+
632
+ #### Why Type Testing?
633
+
634
+ 1. **Type Inference Validation**: Ensure TypeScript correctly infers complex types
635
+ 2. **Generic Constraint Checking**: Verify generic parameter constraints
636
+ 3. **Type Compatibility**: Ensure type definitions match actual usage
637
+ 4. **API Contract Guarantee**: Prevent breaking changes in type definitions
638
+
639
+ #### Basic Type Testing
640
+
630
641
  ```typescript
642
+ import { describe, it, expectTypeOf } from 'vitest';
643
+
631
644
  describe('TypeSafetyTests', () => {
632
645
  it('should maintain type safety', () => {
633
646
  const processor = new DataProcessor<User>();
@@ -636,9 +649,190 @@ describe('TypeSafetyTests', () => {
636
649
  expectTypeOf(processor.process).parameter(0).toEqualTypeOf<User>();
637
650
  expectTypeOf(processor.process).returns.toEqualTypeOf<ProcessedUser>();
638
651
  });
652
+
653
+ it('should infer correct return types', () => {
654
+ const result = getData();
655
+
656
+ // Verify return type
657
+ expectTypeOf(result).toEqualTypeOf<{ id: number; name: string }>();
658
+ expectTypeOf(result).not.toEqualTypeOf<{ id: string; name: string }>();
659
+ });
660
+
661
+ it('should validate parameter types', () => {
662
+ function processUser(user: User): void {
663
+ // implementation
664
+ }
665
+
666
+ // Verify parameter type
667
+ expectTypeOf(processUser).parameter(0).toMatchTypeOf<{ id: number }>();
668
+ expectTypeOf(processUser).parameter(0).toHaveProperty('id');
669
+ });
670
+ });
671
+ ```
672
+
673
+ #### Generic Type Testing
674
+
675
+ ```typescript
676
+ describe('Generic Type Tests', () => {
677
+ it('should work with generic constraints', () => {
678
+ class Storage<T extends { id: number }> {
679
+ store(item: T): T {
680
+ return item;
681
+ }
682
+ }
683
+
684
+ const storage = new Storage<User>();
685
+
686
+ // Verify generic type
687
+ expectTypeOf(storage.store).parameter(0).toMatchTypeOf<User>();
688
+ expectTypeOf(storage.store).returns.toMatchTypeOf<User>();
689
+ });
690
+
691
+ it('should validate complex generic types', () => {
692
+ type ApiResponse<T> = {
693
+ data: T;
694
+ status: number;
695
+ message?: string;
696
+ };
697
+
698
+ const response: ApiResponse<User[]> = {
699
+ data: [],
700
+ status: 200
701
+ };
702
+
703
+ // Verify nested generic type
704
+ expectTypeOf(response).toMatchTypeOf<ApiResponse<User[]>>();
705
+ expectTypeOf(response.data).toEqualTypeOf<User[]>();
706
+ });
707
+ });
708
+ ```
709
+
710
+ #### Union and Intersection Type Testing
711
+
712
+ ```typescript
713
+ describe('Union and Intersection Types', () => {
714
+ it('should handle union types correctly', () => {
715
+ type Result = Success | Error;
716
+ type Success = { status: 'success'; data: string };
717
+ type Error = { status: 'error'; message: string };
718
+
719
+ function handleResult(result: Result): void {
720
+ // implementation
721
+ }
722
+
723
+ // Verify union type
724
+ expectTypeOf(handleResult).parameter(0).toMatchTypeOf<Success>();
725
+ expectTypeOf(handleResult).parameter(0).toMatchTypeOf<Error>();
726
+ });
727
+
728
+ it('should handle intersection types correctly', () => {
729
+ type Timestamped = { createdAt: Date; updatedAt: Date };
730
+ type UserWithTimestamp = User & Timestamped;
731
+
732
+ const user: UserWithTimestamp = {
733
+ id: 1,
734
+ name: 'John',
735
+ createdAt: new Date(),
736
+ updatedAt: new Date()
737
+ };
738
+
739
+ // Verify intersection type contains all properties
740
+ expectTypeOf(user).toHaveProperty('id');
741
+ expectTypeOf(user).toHaveProperty('name');
742
+ expectTypeOf(user).toHaveProperty('createdAt');
743
+ expectTypeOf(user).toHaveProperty('updatedAt');
744
+ });
639
745
  });
640
746
  ```
641
747
 
748
+ #### Type Narrowing Testing
749
+
750
+ ```typescript
751
+ describe('Type Narrowing Tests', () => {
752
+ it('should validate type guards', () => {
753
+ function isString(value: unknown): value is string {
754
+ return typeof value === 'string';
755
+ }
756
+
757
+ const value: unknown = 'test';
758
+
759
+ if (isString(value)) {
760
+ // Within this scope, value should be narrowed to string type
761
+ expectTypeOf(value).toEqualTypeOf<string>();
762
+ }
763
+ });
764
+
765
+ it('should validate discriminated unions', () => {
766
+ type Shape =
767
+ | { kind: 'circle'; radius: number }
768
+ | { kind: 'rectangle'; width: number; height: number };
769
+
770
+ function getArea(shape: Shape): number {
771
+ if (shape.kind === 'circle') {
772
+ // In this branch, shape should be narrowed to circle type
773
+ expectTypeOf(shape).toHaveProperty('radius');
774
+ expectTypeOf(shape).not.toHaveProperty('width');
775
+ return Math.PI * shape.radius ** 2;
776
+ } else {
777
+ // In this branch, shape should be narrowed to rectangle type
778
+ expectTypeOf(shape).toHaveProperty('width');
779
+ expectTypeOf(shape).toHaveProperty('height');
780
+ return shape.width * shape.height;
781
+ }
782
+ }
783
+ });
784
+ });
785
+ ```
786
+
787
+ #### Practical Recommendations
788
+
789
+ 1. **Combine with Runtime Tests**: Type tests should complement runtime tests
790
+
791
+ ```typescript
792
+ describe('Combined Runtime and Type Tests', () => {
793
+ it('should validate both runtime behavior and types', () => {
794
+ function add(a: number, b: number): number {
795
+ return a + b;
796
+ }
797
+
798
+ // Type test
799
+ expectTypeOf(add).parameter(0).toEqualTypeOf<number>();
800
+ expectTypeOf(add).returns.toEqualTypeOf<number>();
801
+
802
+ // Runtime test
803
+ expect(add(1, 2)).toBe(3);
804
+ expect(add(-1, 1)).toBe(0);
805
+ });
806
+ });
807
+ ```
808
+
809
+ 2. **Test Type Inference**: Ensure TypeScript correctly infers types, avoid overusing `any`
810
+
811
+ ```typescript
812
+ describe('Type Inference Tests', () => {
813
+ it('should infer types correctly', () => {
814
+ const data = { id: 1, name: 'John' };
815
+
816
+ // Verify inferred type
817
+ expectTypeOf(data).toEqualTypeOf<{ id: number; name: string }>();
818
+ expectTypeOf(data.id).toEqualTypeOf<number>();
819
+ expectTypeOf(data.name).toEqualTypeOf<string>();
820
+ });
821
+ });
822
+ ```
823
+
824
+ 3. **Use TypeScript Compiler Checks**: Run `tsc --noEmit` in CI to ensure no type errors
825
+
826
+ ```bash
827
+ # Add script in package.json
828
+ {
829
+ "scripts": {
830
+ "type-check": "tsc --noEmit",
831
+ "test": "pnpm type-check && vitest run"
832
+ }
833
+ }
834
+ ```
835
+
642
836
  ---
643
837
 
644
838
  ## Performance Testing
@@ -627,7 +627,20 @@ describe('AsyncService', () => {
627
627
 
628
628
  ### 类型安全测试
629
629
 
630
+ TypeScript 项目的测试不仅要验证运行时行为,还应该确保类型系统的正确性。Vitest 提供了 `expectTypeOf` 工具来进行编译时类型检查。
631
+
632
+ #### 为什么需要类型测试?
633
+
634
+ 1. **类型推断验证**:确保 TypeScript 能正确推断复杂类型
635
+ 2. **泛型约束检查**:验证泛型参数的约束条件
636
+ 3. **类型兼容性**:确保类型定义与实际使用匹配
637
+ 4. **API 契约保证**:防止类型定义的破坏性变更
638
+
639
+ #### 基础类型测试
640
+
630
641
  ```typescript
642
+ import { describe, it, expectTypeOf } from 'vitest';
643
+
631
644
  describe('TypeSafetyTests', () => {
632
645
  it('should maintain type safety', () => {
633
646
  const processor = new DataProcessor<User>();
@@ -636,9 +649,190 @@ describe('TypeSafetyTests', () => {
636
649
  expectTypeOf(processor.process).parameter(0).toEqualTypeOf<User>();
637
650
  expectTypeOf(processor.process).returns.toEqualTypeOf<ProcessedUser>();
638
651
  });
652
+
653
+ it('should infer correct return types', () => {
654
+ const result = getData();
655
+
656
+ // 验证返回值类型
657
+ expectTypeOf(result).toEqualTypeOf<{ id: number; name: string }>();
658
+ expectTypeOf(result).not.toEqualTypeOf<{ id: string; name: string }>();
659
+ });
660
+
661
+ it('should validate parameter types', () => {
662
+ function processUser(user: User): void {
663
+ // implementation
664
+ }
665
+
666
+ // 验证参数类型
667
+ expectTypeOf(processUser).parameter(0).toMatchTypeOf<{ id: number }>();
668
+ expectTypeOf(processUser).parameter(0).toHaveProperty('id');
669
+ });
670
+ });
671
+ ```
672
+
673
+ #### 泛型类型测试
674
+
675
+ ```typescript
676
+ describe('Generic Type Tests', () => {
677
+ it('should work with generic constraints', () => {
678
+ class Storage<T extends { id: number }> {
679
+ store(item: T): T {
680
+ return item;
681
+ }
682
+ }
683
+
684
+ const storage = new Storage<User>();
685
+
686
+ // 验证泛型类型
687
+ expectTypeOf(storage.store).parameter(0).toMatchTypeOf<User>();
688
+ expectTypeOf(storage.store).returns.toMatchTypeOf<User>();
689
+ });
690
+
691
+ it('should validate complex generic types', () => {
692
+ type ApiResponse<T> = {
693
+ data: T;
694
+ status: number;
695
+ message?: string;
696
+ };
697
+
698
+ const response: ApiResponse<User[]> = {
699
+ data: [],
700
+ status: 200
701
+ };
702
+
703
+ // 验证嵌套泛型类型
704
+ expectTypeOf(response).toMatchTypeOf<ApiResponse<User[]>>();
705
+ expectTypeOf(response.data).toEqualTypeOf<User[]>();
706
+ });
707
+ });
708
+ ```
709
+
710
+ #### 联合类型与交叉类型测试
711
+
712
+ ```typescript
713
+ describe('Union and Intersection Types', () => {
714
+ it('should handle union types correctly', () => {
715
+ type Result = Success | Error;
716
+ type Success = { status: 'success'; data: string };
717
+ type Error = { status: 'error'; message: string };
718
+
719
+ function handleResult(result: Result): void {
720
+ // implementation
721
+ }
722
+
723
+ // 验证联合类型
724
+ expectTypeOf(handleResult).parameter(0).toMatchTypeOf<Success>();
725
+ expectTypeOf(handleResult).parameter(0).toMatchTypeOf<Error>();
726
+ });
727
+
728
+ it('should handle intersection types correctly', () => {
729
+ type Timestamped = { createdAt: Date; updatedAt: Date };
730
+ type UserWithTimestamp = User & Timestamped;
731
+
732
+ const user: UserWithTimestamp = {
733
+ id: 1,
734
+ name: 'John',
735
+ createdAt: new Date(),
736
+ updatedAt: new Date()
737
+ };
738
+
739
+ // 验证交叉类型包含所有属性
740
+ expectTypeOf(user).toHaveProperty('id');
741
+ expectTypeOf(user).toHaveProperty('name');
742
+ expectTypeOf(user).toHaveProperty('createdAt');
743
+ expectTypeOf(user).toHaveProperty('updatedAt');
744
+ });
639
745
  });
640
746
  ```
641
747
 
748
+ #### 类型窄化测试
749
+
750
+ ```typescript
751
+ describe('Type Narrowing Tests', () => {
752
+ it('should validate type guards', () => {
753
+ function isString(value: unknown): value is string {
754
+ return typeof value === 'string';
755
+ }
756
+
757
+ const value: unknown = 'test';
758
+
759
+ if (isString(value)) {
760
+ // 在此作用域内,value 应该被窄化为 string 类型
761
+ expectTypeOf(value).toEqualTypeOf<string>();
762
+ }
763
+ });
764
+
765
+ it('should validate discriminated unions', () => {
766
+ type Shape =
767
+ | { kind: 'circle'; radius: number }
768
+ | { kind: 'rectangle'; width: number; height: number };
769
+
770
+ function getArea(shape: Shape): number {
771
+ if (shape.kind === 'circle') {
772
+ // 在此分支,shape 应该被窄化为 circle 类型
773
+ expectTypeOf(shape).toHaveProperty('radius');
774
+ expectTypeOf(shape).not.toHaveProperty('width');
775
+ return Math.PI * shape.radius ** 2;
776
+ } else {
777
+ // 在此分支,shape 应该被窄化为 rectangle 类型
778
+ expectTypeOf(shape).toHaveProperty('width');
779
+ expectTypeOf(shape).toHaveProperty('height');
780
+ return shape.width * shape.height;
781
+ }
782
+ }
783
+ });
784
+ });
785
+ ```
786
+
787
+ #### 实用建议
788
+
789
+ 1. **结合运行时测试**:类型测试应该与运行时测试相辅相成
790
+
791
+ ```typescript
792
+ describe('Combined Runtime and Type Tests', () => {
793
+ it('should validate both runtime behavior and types', () => {
794
+ function add(a: number, b: number): number {
795
+ return a + b;
796
+ }
797
+
798
+ // 类型测试
799
+ expectTypeOf(add).parameter(0).toEqualTypeOf<number>();
800
+ expectTypeOf(add).returns.toEqualTypeOf<number>();
801
+
802
+ // 运行时测试
803
+ expect(add(1, 2)).toBe(3);
804
+ expect(add(-1, 1)).toBe(0);
805
+ });
806
+ });
807
+ ```
808
+
809
+ 2. **测试类型推断**:确保 TypeScript 能正确推断类型,避免过度使用 `any`
810
+
811
+ ```typescript
812
+ describe('Type Inference Tests', () => {
813
+ it('should infer types correctly', () => {
814
+ const data = { id: 1, name: 'John' };
815
+
816
+ // 验证推断的类型
817
+ expectTypeOf(data).toEqualTypeOf<{ id: number; name: string }>();
818
+ expectTypeOf(data.id).toEqualTypeOf<number>();
819
+ expectTypeOf(data.name).toEqualTypeOf<string>();
820
+ });
821
+ });
822
+ ```
823
+
824
+ 3. **使用 TypeScript 编译器检查**:在 CI 中运行 `tsc --noEmit` 确保没有类型错误
825
+
826
+ ```bash
827
+ # 在 package.json 中添加脚本
828
+ {
829
+ "scripts": {
830
+ "type-check": "tsc --noEmit",
831
+ "test": "pnpm type-check && vitest run"
832
+ }
833
+ }
834
+ ```
835
+
642
836
  ---
643
837
 
644
838
  ## 性能测试
@@ -92,17 +92,14 @@ const eslintConfig = [
92
92
  'storybook-static/**'
93
93
  ]
94
94
  },
95
+
95
96
  {
96
97
  files: ['**/*.{js,jsx,ts,tsx}'],
97
98
  languageOptions: {
98
99
  parser: tseslint.parser,
99
100
  parserOptions: {
100
- project: [
101
- './tsconfig.app.json',
102
- './tsconfig.node.json',
103
- './tsconfig.test.json',
104
- './tsconfig.e2e.json'
105
- ],
101
+ // Note: 'project' is removed here to avoid conflict with projectService in the type-checked config below
102
+ // TypeScript files will get type information from the recommendedTypeChecked config
106
103
  tsconfigRootDir: __dirname
107
104
  }
108
105
  },
@@ -116,7 +113,7 @@ const eslintConfig = [
116
113
  rules: {
117
114
  '@qlover-eslint/ts-class-method-return': 'error',
118
115
  '@qlover-eslint/ts-class-member-accessibility': 'error',
119
- '@qlover-eslint/ts-class-override': 'error',
116
+ '@qlover-eslint/ts-class-override': 'off',
120
117
  '@qlover-eslint/require-root-testid': [
121
118
  'error',
122
119
  {
@@ -202,6 +199,81 @@ const eslintConfig = [
202
199
  'import/no-default-export': 'error'
203
200
  }
204
201
  },
202
+
203
+ // TypeScript files with type checking for ts-class-override rule
204
+ // The ts-class-override rule requires full type information to accurately detect:
205
+ // - Methods that override parent class methods (via extends)
206
+ // - Methods that implement interface methods (via implements)
207
+ // Without type checking, the rule falls back to AST-based heuristics which are less accurate
208
+ // This separate config block enables type checking only for TypeScript files to provide
209
+ // accurate override detection while maintaining good performance
210
+ ...tseslint.configs.recommendedTypeChecked.map((config) => ({
211
+ ...config,
212
+ files: ['src/**/*.{ts,tsx}'],
213
+ ignores: [
214
+ '**/dist/**',
215
+ '**/build/**',
216
+ '**/ts-build/**',
217
+ '**/node_modules/**',
218
+ '**/.nx/**',
219
+ '**/.cache/**',
220
+ '**/coverage/**',
221
+ '**/*.d.ts',
222
+ '**/*.config.ts',
223
+ '**/*.test.ts',
224
+ '**/__mocks__/**',
225
+ '**/__tests__/**',
226
+ '**/*.spec.ts',
227
+ ...(config.ignores || [])
228
+ ],
229
+ languageOptions: {
230
+ ...config.languageOptions,
231
+ parserOptions: {
232
+ ...config.languageOptions?.parserOptions,
233
+ project: './tsconfig.app.json',
234
+ tsconfigRootDir: __dirname
235
+ }
236
+ },
237
+ plugins: {
238
+ ...config.plugins,
239
+ '@qlover-eslint': qloverEslint
240
+ },
241
+ rules: {
242
+ ...config.rules,
243
+ // Enable ts-class-override rule with full type information
244
+ // This rule is disabled in the base config above and only enabled here where
245
+ // type information is available, ensuring accurate detection of override relationships
246
+ '@qlover-eslint/ts-class-override': 'error',
247
+ // Disable other type-checked rules to avoid performance impact
248
+ // We only need type checking for ts-class-override, so we disable other
249
+ // type-aware rules that would slow down linting without providing value
250
+ '@typescript-eslint/ban-ts-comment': 'off',
251
+ '@typescript-eslint/restrict-template-expressions': 'off',
252
+ '@typescript-eslint/no-unsafe-assignment': 'off',
253
+ '@typescript-eslint/no-unnecessary-type-assertion': 'off',
254
+ '@typescript-eslint/no-redundant-type-constituents': 'off',
255
+ '@typescript-eslint/no-unsafe-return': 'off',
256
+ '@typescript-eslint/no-empty-object-type': 'off',
257
+ '@typescript-eslint/no-unsafe-call': 'off',
258
+ '@typescript-eslint/no-unsafe-member-access': 'off',
259
+ '@typescript-eslint/no-unsafe-argument': 'off',
260
+ '@typescript-eslint/no-unsafe-enum-comparison': 'off',
261
+ '@typescript-eslint/no-unsafe-literal-comparison': 'off',
262
+ '@typescript-eslint/no-unsafe-nullish-coalescing': 'off',
263
+ '@typescript-eslint/no-unsafe-optional-chaining': 'off',
264
+ '@typescript-eslint/unbound-method': 'off',
265
+ '@typescript-eslint/await-thenable': 'off',
266
+ '@typescript-eslint/no-floating-promises': 'off',
267
+ '@typescript-eslint/no-misused-promises': 'off',
268
+ '@typescript-eslint/require-await': 'off',
269
+ '@typescript-eslint/no-base-to-string': 'off',
270
+ '@typescript-eslint/prefer-promise-reject-errors': 'off',
271
+ '@typescript-eslint/no-duplicate-type-constituents': 'off',
272
+ // Disable @typescript-eslint/no-unused-vars as we use unused-imports/no-unused-vars instead
273
+ '@typescript-eslint/no-unused-vars': 'off',
274
+ '@typescript-eslint/no-explicit-any': 'off',
275
+ }
276
+ })),
205
277
  {
206
278
  // TODO: antd override theme need use import type
207
279
  files: ['src/base/types/deprecated-antd.d.ts'],
@@ -36,8 +36,8 @@
36
36
  "build:staging": "npm run lint && vite build --mode staging",
37
37
  "build:prod": "npm run lint && vite build --mode production",
38
38
  "build:analyze": "vite build --mode production && start dist/stats.html",
39
- "lint": "eslint ./src ./__tests__ ./config ./makes ./e2e",
40
- "lint:fix": "eslint ./src ./__tests__ ./config ./makes ./e2e --ext .ts,.tsx --fix",
39
+ "lint": "eslint",
40
+ "lint:fix": "eslint --ext .ts,.tsx --fix",
41
41
  "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,css,scss,md}\"",
42
42
  "format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,json,css,scss,md}\"",
43
43
  "fix": "npm run lint:fix && npm run format",
@@ -59,6 +59,9 @@ export interface FeApiTransaction<
59
59
  export class FeApiBootstarp implements BootstrapExecutorPlugin {
60
60
  public readonly pluginName = 'FeApiBootstarp';
61
61
 
62
+ /**
63
+ * @override
64
+ */
62
65
  public onBefore({ parameters: { ioc } }: BootstrapContext): void {
63
66
  ioc
64
67
  .get<FeApi>(FeApi)