@@ -2,72 +2,105 @@ import type { Linter } from "eslint";
22
33import { defineConfig } from "@eslint/config-helpers" ;
44import stylisticTs from "@stylistic/eslint-plugin-ts" ;
5+ import { defu } from "defu" ;
56import tseslint from "typescript-eslint" ;
7+ import * as typescriptESLintParserForExtraFiles from "typescript-eslint-parser-for-extra-files" ;
68
79import { __dirname } from "../lib/dir" ;
810import { tsFiles } from "../utils/files" ;
911
10- export const tsConfig = defineConfig ( {
11- extends : [
12- ...( tseslint . configs . recommendedTypeChecked as Linter . Config [ ] ) ,
13- ...( tseslint . configs . stylisticTypeChecked as Linter . Config [ ] ) ,
14- ] ,
15- files : [ tsFiles ] ,
16- languageOptions : {
12+ type TSConfigParams = {
13+ extraFiles : boolean ;
14+ } ;
15+
16+ const DEFAULT_PARAMS = {
17+ extraFiles : false ,
18+ } as const satisfies TSConfigParams ;
19+
20+ export const tsConfig = ( params : Partial < TSConfigParams > = { } ) => {
21+ const resolvedParams = defu ( params , DEFAULT_PARAMS ) ;
22+
23+ return defineConfig ( {
24+ extends : [
25+ ...( tseslint . configs . recommendedTypeChecked as Linter . Config [ ] ) ,
26+ ...( tseslint . configs . stylisticTypeChecked as Linter . Config [ ] ) ,
27+ ] ,
28+ files : [ tsFiles ] ,
29+ languageOptions : getLanguageOptions ( {
30+ extraFiles : resolvedParams . extraFiles ,
31+ } ) ,
32+ name : "@virtual-live-lab/eslint-config/typescript" ,
33+ plugins : {
34+ "@stylistic/ts" : stylisticTs ,
35+ } ,
36+ rules : {
37+ "@stylistic/ts/no-extra-semi" : "error" ,
38+ "@typescript-eslint/adjacent-overload-signatures" : "off" ,
39+ // #175
40+ "@typescript-eslint/array-type" : [
41+ "error" ,
42+ {
43+ default : "array-simple" ,
44+ } ,
45+ ] ,
46+ "@typescript-eslint/ban-tslint-comment" : "off" ,
47+ "@typescript-eslint/class-literal-property-style" : "off" ,
48+ "@typescript-eslint/consistent-generic-constructors" : "off" ,
49+ "@typescript-eslint/consistent-indexed-object-style" : "off" ,
50+ "@typescript-eslint/consistent-type-assertions" : "error" ,
51+ "@typescript-eslint/consistent-type-definitions" : "off" ,
52+ "@typescript-eslint/consistent-type-exports" : "error" ,
53+ "@typescript-eslint/consistent-type-imports" : "error" ,
54+ "@typescript-eslint/no-confusing-non-null-assertion" : "off" ,
55+ "@typescript-eslint/no-deprecated" : "warn" ,
56+ "@typescript-eslint/no-duplicate-enum-values" : "off" ,
57+ "@typescript-eslint/no-import-type-side-effects" : "error" ,
58+ // this is for react-hook-form
59+ "@typescript-eslint/no-misused-promises" : [
60+ "error" ,
61+ {
62+ checksVoidReturn : {
63+ attributes : false ,
64+ } ,
65+ } ,
66+ ] ,
67+ "@typescript-eslint/no-non-null-assertion" : "warn" ,
68+ "@typescript-eslint/no-unsafe-declaration-merging" : "off" ,
69+ "@typescript-eslint/prefer-for-of" : "off" ,
70+ "@typescript-eslint/prefer-function-type" : "off" ,
71+ "@typescript-eslint/promise-function-async" : "error" ,
72+ // #97
73+ "@typescript-eslint/strict-boolean-expressions" : [
74+ "error" ,
75+ {
76+ allowNumber : false ,
77+ } ,
78+ ] ,
79+ } ,
80+ } ) ;
81+ } ;
82+
83+ const getLanguageOptions = (
84+ params : Pick < TSConfigParams , "extraFiles" > ,
85+ ) : Linter . LanguageOptions => {
86+ if ( params . extraFiles ) {
87+ return {
88+ // @ts -expect-error type mismatch, but works
89+ parser : typescriptESLintParserForExtraFiles ,
90+ parserOptions : {
91+ project : true ,
92+ projectService : false ,
93+ tsconfigRootDir : __dirname ,
94+ } ,
95+ } ;
96+ }
97+ return {
1798 parserOptions : {
1899 projectService : {
19100 allowDefaultProject : [ "*.js" , "*.mjs" , "*.cjs" ] ,
20101 defaultProject : `${ __dirname } /tsconfig.json` ,
21102 } ,
22103 tsconfigRootDir : __dirname ,
23104 } ,
24- } ,
25- name : "@virtual-live-lab/eslint-config/typescript" ,
26- plugins : {
27- "@stylistic/ts" : stylisticTs ,
28- } ,
29- rules : {
30- "@stylistic/ts/no-extra-semi" : "error" ,
31- "@typescript-eslint/adjacent-overload-signatures" : "off" ,
32- // #175
33- "@typescript-eslint/array-type" : [
34- "error" ,
35- {
36- default : "array-simple" ,
37- } ,
38- ] ,
39- "@typescript-eslint/ban-tslint-comment" : "off" ,
40- "@typescript-eslint/class-literal-property-style" : "off" ,
41- "@typescript-eslint/consistent-generic-constructors" : "off" ,
42- "@typescript-eslint/consistent-indexed-object-style" : "off" ,
43- "@typescript-eslint/consistent-type-assertions" : "error" ,
44- "@typescript-eslint/consistent-type-definitions" : "off" ,
45- "@typescript-eslint/consistent-type-exports" : "error" ,
46- "@typescript-eslint/consistent-type-imports" : "error" ,
47- "@typescript-eslint/no-confusing-non-null-assertion" : "off" ,
48- "@typescript-eslint/no-deprecated" : "warn" ,
49- "@typescript-eslint/no-duplicate-enum-values" : "off" ,
50- "@typescript-eslint/no-import-type-side-effects" : "error" ,
51- // this is for react-hook-form
52- "@typescript-eslint/no-misused-promises" : [
53- "error" ,
54- {
55- checksVoidReturn : {
56- attributes : false ,
57- } ,
58- } ,
59- ] ,
60- "@typescript-eslint/no-non-null-assertion" : "warn" ,
61- "@typescript-eslint/no-unsafe-declaration-merging" : "off" ,
62- "@typescript-eslint/prefer-for-of" : "off" ,
63- "@typescript-eslint/prefer-function-type" : "off" ,
64- "@typescript-eslint/promise-function-async" : "error" ,
65- // #97
66- "@typescript-eslint/strict-boolean-expressions" : [
67- "error" ,
68- {
69- allowNumber : false ,
70- } ,
71- ] ,
72- } ,
73- } ) ;
105+ } ;
106+ } ;
0 commit comments