@ttsc/lint 0.8.1 → 0.10.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.
package/README.md CHANGED
@@ -11,7 +11,7 @@
11
11
 
12
12
  Lint as compile errors.
13
13
 
14
- Rules run inside `ttsc`'s `typescript-go` type-check pass one compile, both checks.
14
+ Type errors and lint violations appear in one `ttsc` run.
15
15
 
16
16
  ## Demonstration
17
17
 
@@ -54,15 +54,28 @@ CI that already runs `ttsc` blocks on lint with no extra wiring.
54
54
 
55
55
  ## Setup
56
56
 
57
- Install `ttsc`, TypeScript-Go, and the lint plugin:
57
+ Install `ttsc` and TypeScript-Go, then the lint plugin:
58
58
 
59
59
  ```bash
60
- npm install -D ttsc @typescript/native-preview @ttsc/lint
60
+ npm install -D ttsc @typescript/native-preview
61
+ npm install -D @ttsc/lint
61
62
  ```
62
63
 
63
- Add the plugin under `compilerOptions.plugins` in your `tsconfig.json`.
64
+ Add `lint.config.ts`, or reuse an existing `eslint.config.ts`, next to your project config. If no config file or inline config is found, the compile fails.
64
65
 
65
- Keep `@ttsc/lint` as the first plugin entry — see [Plugin order](#plugin-order).
66
+ ```ts
67
+ // lint.config.ts
68
+ import type { TtscLintConfig } from "@ttsc/lint/config";
69
+
70
+ export default {
71
+ "no-var": "error",
72
+ "prefer-const": "error",
73
+ "no-explicit-any": "warning",
74
+ "no-console": "off",
75
+ } satisfies TtscLintConfig;
76
+ ```
77
+
78
+ Use `compilerOptions.plugins` only when the project needs inline config or an explicit config file path.
66
79
 
67
80
  ```jsonc
68
81
  {
@@ -93,137 +106,13 @@ npx ttsx src/index.ts
93
106
  - Under `ttsx`, lint errors stop the program before your entrypoint runs.
94
107
  - Lint warnings are printed without changing the exit code.
95
108
 
96
- ### External config file
97
-
98
- You can also keep the rules in a standalone file and reference it from `tsconfig.json`:
99
-
100
- ```jsonc
101
- {
102
- "compilerOptions": {
103
- "plugins": [
104
- {
105
- "transform": "@ttsc/lint",
106
- "config": "./ttsc-lint.config.ts",
107
- },
108
- ],
109
- },
110
- }
111
- ```
112
-
113
- ```ts
114
- // ttsc-lint.config.ts
115
- import type { TtscLintConfig } from "@ttsc/lint/config";
116
-
117
- export default {
118
- "no-var": "error",
119
- "prefer-const": "error",
120
- "no-explicit-any": "warning",
121
- "no-console": "off",
122
- } satisfies TtscLintConfig;
123
- ```
124
-
125
- The `config` field accepts:
126
-
127
- - An inline object (shown earlier), **or** a path to a file ending in `.json`, `.js`, `.cjs`, `.mjs`, `.ts`, `.cts`, or `.mts`.
128
- - For JS/TS configs: a `default` export, a named `config` export, a direct module export, or a function that returns the object.
129
- - If `config` is omitted, `@ttsc/lint` discovers the nearest `eslint.config.js`, `eslint.config.mjs`, `eslint.config.cjs`, `eslint.config.ts`, `eslint.config.mts`, or `eslint.config.cts` from the owning `tsconfig.json` directory upward.
130
- - Inline objects use the standard `@ttsc/lint` native rule map shape.
131
- - Standalone config files may additionally export ESLint flat-config-style objects or arrays. `@ttsc/lint` lowers their `basePath`, `files`, `ignores`, object/array `extends`, and `rules` fields into native per-file rule maps, accepts ESLint severity tuples, and maps `@typescript-eslint/<rule>` keys to native rule names when a matching native rule exists.
132
- - Relative paths resolve from the directory of the owning `tsconfig.json`.
133
-
134
- For example, a flat-config-style file can enable native `@ttsc/lint` rules with
135
- ESLint or `@typescript-eslint/*` keys:
136
-
137
- ```ts
138
- // eslint.config.ts
139
- import type { Linter } from "eslint";
140
-
141
- const config = [
142
- {
143
- rules: {
144
- "@typescript-eslint/no-explicit-any": "error",
145
- "@typescript-eslint/consistent-type-imports": [
146
- "warning",
147
- { fixStyle: "inline-type-imports" },
148
- ],
149
- "no-console": "off",
150
- },
151
- },
152
- ] satisfies Linter.Config[];
153
-
154
- export default config;
155
- ```
156
-
157
- Config factories can be used when they return a resolved flat config object or
158
- array. Current `typescript-eslint` versions prefer ESLint's `defineConfig(...)`;
159
- existing configs that still use `typescript-eslint`'s `config(...)` are readable
160
- when they export the resolved object/array shape:
161
-
162
- ```ts
163
- // eslint.config.ts
164
- import tseslint, { type ConfigArray } from "typescript-eslint";
165
-
166
- const config = tseslint.config({
167
- extends: [tseslint.configs.recommended],
168
- rules: {
169
- "@typescript-eslint/no-explicit-any": "error",
170
- },
171
- }) satisfies ConfigArray;
172
-
173
- export default config;
174
- ```
175
-
176
- When a project has `eslint` installed and the external config is an
177
- `eslint.config.*` file, or the config uses runtime-only fields such as `plugins`,
178
- `languageOptions`, `processor`, `settings`, or string `extends`, `@ttsc/lint`
179
- delegates diagnostics to the installed ESLint runtime and forwards its rule ids,
180
- severities, messages, and locations. This is the path that runs external
181
- RuleModules such as `@typescript-eslint/no-floating-promises`; typed
182
- typescript-eslint rules work when your ESLint config supplies the usual parser
183
- and `parserOptions.project` / `projectService` settings.
109
+ ### Config Files
184
110
 
185
- When ESLint is not installed and the config can be represented as native rules,
186
- `@ttsc/lint` falls back to the lowered native rule map. That fallback supports
187
- `files`, `ignores`, `basePath`, object/array `extends`, `rules`, severity tuples,
188
- and `@typescript-eslint/` or `typescript-eslint/` rule prefixes. Runtime-only
189
- features such as `plugins`, `languageOptions`, `processor`, `settings`,
190
- `linterOptions`, or string `extends` require ESLint to be installed.
191
-
192
- Inline disable comments are respected in both paths. Use the ESLint forms
193
- `eslint-disable-next-line`, `eslint-disable-line`, `eslint-disable`, and
194
- `eslint-enable`; the native engine also accepts the `lint-*` aliases for the
195
- same directives.
196
-
197
- ## Plugin order
198
-
199
- `@ttsc/lint` must be the first plugin in `compilerOptions.plugins`.
200
-
201
- It inspects the source you wrote, so transform plugins such as `@ttsc/banner`, `@ttsc/paths`, and `@ttsc/strip` have to come after it.
202
-
203
- ```jsonc
204
- {
205
- "compilerOptions": {
206
- "plugins": [
207
- // Keep lint first.
208
- {
209
- "transform": "@ttsc/lint",
210
- "config": { "no-var": "error", "prefer-const": "error" },
211
- },
212
-
213
- // First-party utilities use their documented transform order.
214
- { "transform": "@ttsc/banner", "banner": "License MIT" },
215
- { "transform": "@ttsc/paths" },
216
- { "transform": "@ttsc/strip", "calls": ["console.log"] },
217
- ],
218
- },
219
- }
220
- ```
111
+ By default, `@ttsc/lint` reads config files such as `lint.config.ts` or `eslint.config.ts` next to the selected `tsconfig.json`.
221
112
 
222
113
  ## Scope
223
114
 
224
- Diagnostic-only today: no autofix and no bundled recommended preset. The native
225
- engine does not load custom Go rules; external ESLint RuleModules run through
226
- the installed ESLint runtime path described above.
115
+ Diagnostic-only today: no autofix and no bundled recommended preset.
227
116
 
228
117
  ## Rules
229
118
 
@@ -240,135 +129,135 @@ Rules are off until you enable them:
240
129
 
241
130
  Rule severities are `"error"`, `"warning"`, and `"off"`.
242
131
 
243
- The rule corpus is tested in `tests/lint/cases/*.ts`, which is the best place to check the exact patterns currently covered. Each rule below links to its tested fixture:
244
-
245
- - [`adjacent-overload-signatures`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/adjacent-overload-signatures.ts): keeps overload declarations for the same member adjacent.
246
- - [`array-type`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/array-type.ts): prefers `T[]` and `readonly T[]` over array helper types.
247
- - [`ban-ts-comment`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/ban-ts-comment.ts): rejects TypeScript suppression comments such as `@ts-ignore`.
248
- - [`ban-tslint-comment`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/ban-tslint-comment.ts): rejects obsolete `tslint:` comments.
249
- - [`consistent-indexed-object-style`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/consistent-indexed-object-style.ts): prefers `Record` for single index-signature object types.
250
- - [`consistent-type-assertions`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/consistent-type-assertions.ts): prefers `as` type assertions over angle-bracket assertions.
251
- - [`consistent-type-definitions`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/consistent-type-definitions.ts): prefers interfaces for object-shaped type definitions.
252
- - [`consistent-type-imports`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/consistent-type-imports/violation.ts): uses `import type` when imported names are type-only.
253
- - [`dot-notation`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/dot-notation.ts): prefers dot property access when a string-literal key is a valid identifier.
254
- - [`eqeqeq`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/eqeqeq.ts): requires strict equality operators.
255
- - [`for-direction`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/for-direction.ts): catches loop counters updated in the wrong direction.
256
- - [`no-alert`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-alert.ts): rejects `alert`, `confirm`, and `prompt`.
257
- - [`no-array-constructor`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-array-constructor.ts): rejects `Array` constructor calls.
258
- - [`no-array-delete`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-array-delete.ts): rejects `delete` on array elements.
259
- - [`no-async-promise-executor`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-async-promise-executor.ts): rejects async Promise executors.
260
- - [`no-bitwise`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-bitwise.ts): rejects bitwise operators.
261
- - [`no-caller`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-caller.ts): rejects `arguments.caller` and `arguments.callee`.
262
- - [`no-case-declarations`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-case-declarations.ts): rejects lexical declarations directly inside `case` clauses.
263
- - [`no-class-assign`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-class-assign.ts): rejects reassignment of class declarations.
264
- - [`no-compare-neg-zero`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-compare-neg-zero.ts): rejects comparisons against `-0`.
265
- - [`no-cond-assign`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-cond-assign.ts): rejects assignments inside conditions.
266
- - [`no-confusing-non-null-assertion`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-confusing-non-null-assertion.ts): rejects confusing non-null assertions next to equality checks.
267
- - [`no-console`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-console.ts): rejects `console` calls.
268
- - [`no-constant-condition`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-constant-condition.ts): rejects constant conditions.
269
- - [`no-continue`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-continue.ts): rejects `continue` statements.
270
- - [`no-control-regex`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-control-regex.ts): rejects control characters in regular expressions.
271
- - [`no-debugger`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-debugger.ts): rejects `debugger` statements.
272
- - [`no-delete-var`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-delete-var.ts): rejects deleting variables.
273
- - [`no-dupe-args`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-dupe-args.ts): rejects duplicate function parameters.
274
- - [`no-dupe-else-if`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-dupe-else-if.ts): rejects repeated `else if` conditions.
275
- - [`no-dupe-keys`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-dupe-keys.ts): rejects duplicate object keys.
276
- - [`no-duplicate-case`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-duplicate-case.ts): rejects duplicate `switch` case labels.
277
- - [`no-duplicate-enum-values`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-duplicate-enum-values.ts): rejects duplicate enum member values.
278
- - [`no-dynamic-delete`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-dynamic-delete.ts): rejects `delete` on dynamically computed property keys.
279
- - [`no-empty`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-empty.ts): rejects empty blocks.
280
- - [`no-empty-character-class`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-empty-character-class.ts): rejects empty regex character classes.
281
- - [`no-empty-function`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-empty-function.ts): rejects empty functions.
282
- - [`no-empty-interface`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-empty-interface.ts): rejects empty interfaces.
283
- - [`no-empty-object-type`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-empty-object-type.ts): rejects empty object type literals.
284
- - [`no-empty-pattern`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-empty-pattern.ts): rejects empty destructuring patterns.
285
- - [`no-empty-static-block`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-empty-static-block.ts): rejects empty class static blocks.
286
- - [`no-eq-null`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-eq-null.ts): rejects loose null comparisons.
287
- - [`no-eval`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-eval.ts): rejects `eval`.
288
- - [`no-ex-assign`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-ex-assign.ts): rejects reassignment of caught exceptions.
289
- - [`no-explicit-any`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-explicit-any.ts): rejects explicit `any`.
290
- - [`no-extra-bind`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-extra-bind.ts): rejects unnecessary `.bind()` calls.
291
- - [`no-extra-boolean-cast`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-extra-boolean-cast.ts): rejects redundant boolean casts.
292
- - [`no-extra-non-null-assertion`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-extra-non-null-assertion.ts): rejects repeated non-null assertions.
293
- - [`no-fallthrough`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-fallthrough.ts): rejects unmarked `switch` fallthrough.
294
- - [`no-func-assign`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-func-assign.ts): rejects reassignment of function declarations.
295
- - [`no-inferrable-types`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-inferrable-types.ts): rejects type annotations TypeScript can infer.
296
- - [`no-inner-declarations`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-inner-declarations.ts): rejects function declarations nested in blocks.
297
- - [`no-irregular-whitespace`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-irregular-whitespace.ts): rejects irregular whitespace.
298
- - [`no-iterator`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-iterator.ts): rejects `__iterator__`.
299
- - [`no-labels`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-labels.ts): rejects labels.
300
- - [`no-lone-blocks`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-lone-blocks.ts): rejects unnecessary standalone blocks.
301
- - [`no-lonely-if`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-lonely-if.ts): rejects `if` as the only statement in an `else`.
302
- - [`no-loss-of-precision`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-loss-of-precision.ts): rejects number literals that lose precision.
303
- - [`no-misleading-character-class`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-misleading-character-class.ts): rejects misleading regex character classes.
304
- - [`no-misused-new`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-misused-new.ts): rejects constructor-like signatures in interfaces.
305
- - [`no-multi-assign`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-multi-assign.ts): rejects chained assignments.
306
- - [`no-multi-str`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-multi-str.ts): rejects multiline string escapes.
307
- - [`no-namespace`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-namespace.ts): rejects non-ambient namespaces.
308
- - [`no-negated-condition`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-negated-condition.ts): rejects negated conditions with an `else`.
309
- - [`no-nested-ternary`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-nested-ternary.ts): rejects nested ternary expressions.
310
- - [`no-new`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-new.ts): rejects `new` expressions used only for side effects.
311
- - [`no-new-func`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-new-func.ts): rejects `Function` constructors.
312
- - [`no-new-wrappers`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-new-wrappers.ts): rejects primitive wrapper constructors.
313
- - [`no-non-null-asserted-nullish-coalescing`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-non-null-asserted-nullish-coalescing.ts): rejects non-null assertions next to `??`.
314
- - [`no-non-null-asserted-optional-chain`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-non-null-asserted-optional-chain.ts): rejects non-null assertions on optional chains.
315
- - [`no-non-null-assertion`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-non-null-assertion.ts): rejects postfix non-null assertions.
316
- - [`no-obj-calls`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-obj-calls.ts): rejects calling global objects as functions.
317
- - [`no-object-constructor`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-object-constructor.ts): rejects `new Object()`.
318
- - [`no-octal`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-octal.ts): rejects legacy octal literals.
319
- - [`no-octal-escape`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-octal-escape.ts): rejects octal escape sequences.
320
- - [`no-plusplus`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-plusplus.ts): rejects `++` and `--`.
321
- - [`no-promise-executor-return`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-promise-executor-return.ts): rejects returned values from Promise executors.
322
- - [`no-proto`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-proto.ts): rejects `__proto__`.
323
- - [`no-prototype-builtins`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-prototype-builtins.ts): rejects direct `Object.prototype` method calls.
324
- - [`no-regex-spaces`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-regex-spaces.ts): rejects repeated literal spaces in regexes.
325
- - [`no-require-imports`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-require-imports.ts): rejects CommonJS `require` imports.
326
- - [`no-return-assign`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-return-assign.ts): rejects assignments in `return`.
327
- - [`no-script-url`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-script-url.ts): rejects `javascript:` URLs.
328
- - [`no-self-assign`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-self-assign.ts): rejects assignments to the same value.
329
- - [`no-self-compare`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-self-compare.ts): rejects comparing a value to itself.
330
- - [`no-sequences`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-sequences.ts): rejects comma expressions.
331
- - [`no-setter-return`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-setter-return.ts): rejects returned values from setters.
332
- - [`no-shadow-restricted-names`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-shadow-restricted-names.ts): rejects shadowing restricted globals.
333
- - [`no-sparse-arrays`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-sparse-arrays.ts): rejects sparse arrays.
334
- - [`no-template-curly-in-string`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-template-curly-in-string.ts): rejects `${...}` text inside normal strings.
335
- - [`no-this-alias`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-this-alias.ts): rejects aliasing `this` to locals.
336
- - [`no-throw-literal`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-throw-literal.ts): rejects throwing literals.
337
- - [`no-undef-init`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-undef-init.ts): rejects initializing to `undefined`.
338
- - [`no-undefined`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-undefined.ts): rejects the global `undefined` identifier.
339
- - [`no-unnecessary-type-constraint`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-unnecessary-type-constraint.ts): rejects redundant `extends any` and `extends unknown` constraints.
340
- - [`no-unneeded-ternary`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-unneeded-ternary.ts): rejects redundant ternary expressions.
341
- - [`no-unsafe-declaration-merging`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-unsafe-declaration-merging.ts): rejects unsafe class/interface declaration merging.
342
- - [`no-unsafe-finally`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-unsafe-finally.ts): rejects control flow from `finally`.
343
- - [`no-unsafe-function-type`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-unsafe-function-type.ts): rejects the unsafe `Function` type.
344
- - [`no-unsafe-negation`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-unsafe-negation.ts): rejects unsafe negation before relational checks.
345
- - [`no-unused-expressions`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-unused-expressions.ts): rejects expression statements with no effect.
346
- - [`no-unused-labels`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-unused-labels.ts): rejects labels that no `break` or `continue` targets.
347
- - [`no-useless-call`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-useless-call.ts): rejects unnecessary `.call()` and `.apply()`.
348
- - [`no-useless-catch`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-useless-catch.ts): rejects catch blocks that only rethrow.
349
- - [`no-useless-computed-key`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-useless-computed-key.ts): rejects unnecessary computed property keys.
350
- - [`no-useless-concat`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-useless-concat.ts): rejects unnecessary string concatenation.
351
- - [`no-useless-constructor`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-useless-constructor.ts): rejects empty constructors with no parameters.
352
- - [`no-useless-rename`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-useless-rename.ts): rejects import/export/destructure renames to the same name.
353
- - [`no-var`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-var.ts): rejects `var`.
354
- - [`no-with`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-with.ts): rejects `with` statements.
355
- - [`no-wrapper-object-types`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/no-wrapper-object-types.ts): rejects boxed object type names such as `String` and `Boolean`.
356
- - [`object-shorthand`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/object-shorthand.ts): requires object property shorthand where possible.
357
- - [`operator-assignment`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/operator-assignment.ts): prefers compound assignment operators.
358
- - [`prefer-as-const`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/prefer-as-const.ts): prefers `as const` for literal assertions.
359
- - [`prefer-const`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/prefer-const.ts): prefers `const` for `let` bindings that are never reassigned.
360
- - [`prefer-enum-initializers`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/prefer-enum-initializers.ts): requires explicit enum member initializers.
361
- - [`prefer-exponentiation-operator`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/prefer-exponentiation-operator.ts): prefers `**` over `Math.pow`.
362
- - [`prefer-for-of`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/prefer-for-of.ts): prefers `for...of` for simple array iteration.
363
- - [`prefer-function-type`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/prefer-function-type.ts): prefers function type aliases over single-call interfaces.
364
- - [`prefer-literal-enum-member`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/prefer-literal-enum-member.ts): prefers literal enum member initializers over computed expressions.
365
- - [`prefer-namespace-keyword`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/prefer-namespace-keyword.ts): prefers `namespace` over TypeScript's legacy `module` keyword.
366
- - [`prefer-spread`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/prefer-spread.ts): prefers spread arguments over `.apply`.
367
- - [`prefer-template`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/prefer-template.ts): prefers template literals over string concatenation.
368
- - [`radix`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/radix.ts): requires a radix argument for `parseInt`.
369
- - [`require-yield`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/require-yield.ts): requires generator functions to contain `yield`.
370
- - [`triple-slash-reference`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/triple-slash-reference/violation.ts): rejects triple-slash reference directives.
371
- - [`use-isnan`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/use-isnan.ts): requires `Number.isNaN`/`isNaN` for `NaN` checks.
372
- - [`valid-typeof`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/valid-typeof.ts): restricts `typeof` comparisons to valid strings.
373
- - [`vars-on-top`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/vars-on-top.ts): requires `var` declarations at the top of their scope.
374
- - [`yoda`](https://github.com/samchon/ttsc/blob/master/tests/lint/cases/yoda.ts): rejects literal-first comparisons.
132
+ The rule corpus is tested in `tests/test-lint/src/cases/*.ts`, which is the best place to check the exact patterns currently covered. Each rule below links to its tested fixture:
133
+
134
+ - [`adjacent-overload-signatures`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/adjacent-overload-signatures.ts): keeps overload declarations for the same member adjacent.
135
+ - [`array-type`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/array-type.ts): prefers `T[]` and `readonly T[]` over array helper types.
136
+ - [`ban-ts-comment`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/ban-ts-comment.ts): rejects TypeScript suppression comments such as `@ts-ignore`.
137
+ - [`ban-tslint-comment`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/ban-tslint-comment.ts): rejects obsolete `tslint:` comments.
138
+ - [`consistent-indexed-object-style`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/consistent-indexed-object-style.ts): prefers `Record` for single index-signature object types.
139
+ - [`consistent-type-assertions`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/consistent-type-assertions.ts): prefers `as` type assertions over angle-bracket assertions.
140
+ - [`consistent-type-definitions`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/consistent-type-definitions.ts): prefers interfaces for object-shaped type definitions.
141
+ - [`consistent-type-imports`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/consistent-type-imports/violation.ts): uses `import type` when imported names are type-only.
142
+ - [`dot-notation`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/dot-notation.ts): prefers dot property access when a string-literal key is a valid identifier.
143
+ - [`eqeqeq`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/eqeqeq.ts): requires strict equality operators.
144
+ - [`for-direction`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/for-direction.ts): catches loop counters updated in the wrong direction.
145
+ - [`no-alert`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-alert.ts): rejects `alert`, `confirm`, and `prompt`.
146
+ - [`no-array-constructor`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-array-constructor.ts): rejects `Array` constructor calls.
147
+ - [`no-array-delete`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-array-delete.ts): rejects `delete` on array elements.
148
+ - [`no-async-promise-executor`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-async-promise-executor.ts): rejects async Promise executors.
149
+ - [`no-bitwise`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-bitwise.ts): rejects bitwise operators.
150
+ - [`no-caller`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-caller.ts): rejects `arguments.caller` and `arguments.callee`.
151
+ - [`no-case-declarations`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-case-declarations.ts): rejects lexical declarations directly inside `case` clauses.
152
+ - [`no-class-assign`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-class-assign.ts): rejects reassignment of class declarations.
153
+ - [`no-compare-neg-zero`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-compare-neg-zero.ts): rejects comparisons against `-0`.
154
+ - [`no-cond-assign`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-cond-assign.ts): rejects assignments inside conditions.
155
+ - [`no-confusing-non-null-assertion`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-confusing-non-null-assertion.ts): rejects confusing non-null assertions next to equality checks.
156
+ - [`no-console`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-console.ts): rejects `console` calls.
157
+ - [`no-constant-condition`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-constant-condition.ts): rejects constant conditions.
158
+ - [`no-continue`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-continue.ts): rejects `continue` statements.
159
+ - [`no-control-regex`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-control-regex.ts): rejects control characters in regular expressions.
160
+ - [`no-debugger`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-debugger.ts): rejects `debugger` statements.
161
+ - [`no-delete-var`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-delete-var.ts): rejects deleting variables.
162
+ - [`no-dupe-args`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-dupe-args.ts): rejects duplicate function parameters.
163
+ - [`no-dupe-else-if`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-dupe-else-if.ts): rejects repeated `else if` conditions.
164
+ - [`no-dupe-keys`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-dupe-keys.ts): rejects duplicate object keys.
165
+ - [`no-duplicate-case`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-duplicate-case.ts): rejects duplicate `switch` case labels.
166
+ - [`no-duplicate-enum-values`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-duplicate-enum-values.ts): rejects duplicate enum member values.
167
+ - [`no-dynamic-delete`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-dynamic-delete.ts): rejects `delete` on dynamically computed property keys.
168
+ - [`no-empty`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-empty.ts): rejects empty blocks.
169
+ - [`no-empty-character-class`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-empty-character-class.ts): rejects empty regex character classes.
170
+ - [`no-empty-function`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-empty-function.ts): rejects empty functions.
171
+ - [`no-empty-interface`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-empty-interface.ts): rejects empty interfaces.
172
+ - [`no-empty-object-type`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-empty-object-type.ts): rejects empty object type literals.
173
+ - [`no-empty-pattern`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-empty-pattern.ts): rejects empty destructuring patterns.
174
+ - [`no-empty-static-block`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-empty-static-block.ts): rejects empty class static blocks.
175
+ - [`no-eq-null`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-eq-null.ts): rejects loose null comparisons.
176
+ - [`no-eval`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-eval.ts): rejects `eval`.
177
+ - [`no-ex-assign`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-ex-assign.ts): rejects reassignment of caught exceptions.
178
+ - [`no-explicit-any`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-explicit-any.ts): rejects explicit `any`.
179
+ - [`no-extra-bind`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-extra-bind.ts): rejects unnecessary `.bind()` calls.
180
+ - [`no-extra-boolean-cast`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-extra-boolean-cast.ts): rejects redundant boolean casts.
181
+ - [`no-extra-non-null-assertion`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-extra-non-null-assertion.ts): rejects repeated non-null assertions.
182
+ - [`no-fallthrough`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-fallthrough.ts): rejects unmarked `switch` fallthrough.
183
+ - [`no-func-assign`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-func-assign.ts): rejects reassignment of function declarations.
184
+ - [`no-inferrable-types`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-inferrable-types.ts): rejects type annotations TypeScript can infer.
185
+ - [`no-inner-declarations`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-inner-declarations.ts): rejects function declarations nested in blocks.
186
+ - [`no-irregular-whitespace`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-irregular-whitespace.ts): rejects irregular whitespace.
187
+ - [`no-iterator`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-iterator.ts): rejects `__iterator__`.
188
+ - [`no-labels`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-labels.ts): rejects labels.
189
+ - [`no-lone-blocks`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-lone-blocks.ts): rejects unnecessary standalone blocks.
190
+ - [`no-lonely-if`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-lonely-if.ts): rejects `if` as the only statement in an `else`.
191
+ - [`no-loss-of-precision`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-loss-of-precision.ts): rejects number literals that lose precision.
192
+ - [`no-misleading-character-class`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-misleading-character-class.ts): rejects misleading regex character classes.
193
+ - [`no-misused-new`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-misused-new.ts): rejects constructor-like signatures in interfaces.
194
+ - [`no-multi-assign`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-multi-assign.ts): rejects chained assignments.
195
+ - [`no-multi-str`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-multi-str.ts): rejects multiline string escapes.
196
+ - [`no-namespace`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-namespace.ts): rejects non-ambient namespaces.
197
+ - [`no-negated-condition`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-negated-condition.ts): rejects negated conditions with an `else`.
198
+ - [`no-nested-ternary`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-nested-ternary.ts): rejects nested ternary expressions.
199
+ - [`no-new`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-new.ts): rejects `new` expressions used only for side effects.
200
+ - [`no-new-func`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-new-func.ts): rejects `Function` constructors.
201
+ - [`no-new-wrappers`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-new-wrappers.ts): rejects primitive wrapper constructors.
202
+ - [`no-non-null-asserted-nullish-coalescing`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-non-null-asserted-nullish-coalescing.ts): rejects non-null assertions next to `??`.
203
+ - [`no-non-null-asserted-optional-chain`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-non-null-asserted-optional-chain.ts): rejects non-null assertions on optional chains.
204
+ - [`no-non-null-assertion`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-non-null-assertion.ts): rejects postfix non-null assertions.
205
+ - [`no-obj-calls`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-obj-calls.ts): rejects calling global objects as functions.
206
+ - [`no-object-constructor`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-object-constructor.ts): rejects `new Object()`.
207
+ - [`no-octal`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-octal.ts): rejects legacy octal literals.
208
+ - [`no-octal-escape`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-octal-escape.ts): rejects octal escape sequences.
209
+ - [`no-plusplus`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-plusplus.ts): rejects `++` and `--`.
210
+ - [`no-promise-executor-return`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-promise-executor-return.ts): rejects returned values from Promise executors.
211
+ - [`no-proto`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-proto.ts): rejects `__proto__`.
212
+ - [`no-prototype-builtins`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-prototype-builtins.ts): rejects direct `Object.prototype` method calls.
213
+ - [`no-regex-spaces`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-regex-spaces.ts): rejects repeated literal spaces in regexes.
214
+ - [`no-require-imports`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-require-imports.ts): rejects CommonJS `require` imports.
215
+ - [`no-return-assign`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-return-assign.ts): rejects assignments in `return`.
216
+ - [`no-script-url`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-script-url.ts): rejects `javascript:` URLs.
217
+ - [`no-self-assign`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-self-assign.ts): rejects assignments to the same value.
218
+ - [`no-self-compare`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-self-compare.ts): rejects comparing a value to itself.
219
+ - [`no-sequences`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-sequences.ts): rejects comma expressions.
220
+ - [`no-setter-return`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-setter-return.ts): rejects returned values from setters.
221
+ - [`no-shadow-restricted-names`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-shadow-restricted-names.ts): rejects shadowing restricted globals.
222
+ - [`no-sparse-arrays`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-sparse-arrays.ts): rejects sparse arrays.
223
+ - [`no-template-curly-in-string`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-template-curly-in-string.ts): rejects `${...}` text inside normal strings.
224
+ - [`no-this-alias`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-this-alias.ts): rejects aliasing `this` to locals.
225
+ - [`no-throw-literal`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-throw-literal.ts): rejects throwing literals.
226
+ - [`no-undef-init`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-undef-init.ts): rejects initializing to `undefined`.
227
+ - [`no-undefined`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-undefined.ts): rejects the global `undefined` identifier.
228
+ - [`no-unnecessary-type-constraint`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-unnecessary-type-constraint.ts): rejects redundant `extends any` and `extends unknown` constraints.
229
+ - [`no-unneeded-ternary`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-unneeded-ternary.ts): rejects redundant ternary expressions.
230
+ - [`no-unsafe-declaration-merging`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-unsafe-declaration-merging.ts): rejects unsafe class/interface declaration merging.
231
+ - [`no-unsafe-finally`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-unsafe-finally.ts): rejects control flow from `finally`.
232
+ - [`no-unsafe-function-type`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-unsafe-function-type.ts): rejects the unsafe `Function` type.
233
+ - [`no-unsafe-negation`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-unsafe-negation.ts): rejects unsafe negation before relational checks.
234
+ - [`no-unused-expressions`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-unused-expressions.ts): rejects expression statements with no effect.
235
+ - [`no-unused-labels`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-unused-labels.ts): rejects labels that no `break` or `continue` targets.
236
+ - [`no-useless-call`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-useless-call.ts): rejects unnecessary `.call()` and `.apply()`.
237
+ - [`no-useless-catch`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-useless-catch.ts): rejects catch blocks that only rethrow.
238
+ - [`no-useless-computed-key`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-useless-computed-key.ts): rejects unnecessary computed property keys.
239
+ - [`no-useless-concat`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-useless-concat.ts): rejects unnecessary string concatenation.
240
+ - [`no-useless-constructor`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-useless-constructor.ts): rejects empty constructors with no parameters.
241
+ - [`no-useless-rename`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-useless-rename.ts): rejects import/export/destructure renames to the same name.
242
+ - [`no-var`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-var.ts): rejects `var`.
243
+ - [`no-with`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-with.ts): rejects `with` statements.
244
+ - [`no-wrapper-object-types`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-wrapper-object-types.ts): rejects boxed object type names such as `String` and `Boolean`.
245
+ - [`object-shorthand`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/object-shorthand.ts): requires object property shorthand where possible.
246
+ - [`operator-assignment`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/operator-assignment.ts): prefers compound assignment operators.
247
+ - [`prefer-as-const`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-as-const.ts): prefers `as const` for literal assertions.
248
+ - [`prefer-const`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-const.ts): prefers `const` for `let` bindings that are never reassigned.
249
+ - [`prefer-enum-initializers`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-enum-initializers.ts): requires explicit enum member initializers.
250
+ - [`prefer-exponentiation-operator`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-exponentiation-operator.ts): prefers `**` over `Math.pow`.
251
+ - [`prefer-for-of`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-for-of.ts): prefers `for...of` for simple array iteration.
252
+ - [`prefer-function-type`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-function-type.ts): prefers function type aliases over single-call interfaces.
253
+ - [`prefer-literal-enum-member`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-literal-enum-member.ts): prefers literal enum member initializers over computed expressions.
254
+ - [`prefer-namespace-keyword`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-namespace-keyword.ts): prefers `namespace` over TypeScript's legacy `module` keyword.
255
+ - [`prefer-spread`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-spread.ts): prefers spread arguments over `.apply`.
256
+ - [`prefer-template`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-template.ts): prefers template literals over string concatenation.
257
+ - [`radix`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/radix.ts): requires a radix argument for `parseInt`.
258
+ - [`require-yield`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/require-yield.ts): requires generator functions to contain `yield`.
259
+ - [`triple-slash-reference`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/triple-slash-reference/violation.ts): rejects triple-slash reference directives.
260
+ - [`use-isnan`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/use-isnan.ts): requires `Number.isNaN`/`isNaN` for `NaN` checks.
261
+ - [`valid-typeof`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/valid-typeof.ts): restricts `typeof` comparisons to valid strings.
262
+ - [`vars-on-top`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/vars-on-top.ts): requires `var` declarations at the top of their scope.
263
+ - [`yoda`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/yoda.ts): rejects literal-first comparisons.
package/lib/index.d.ts CHANGED
@@ -1,4 +1,15 @@
1
- import type { ITtscPlugin, ITtscPluginFactoryContext } from "ttsc";
2
1
  import type { ITtscLintPluginConfig } from "./structures";
3
2
  export * from "./structures/index";
4
- export default function createTtscPlugin(_context: ITtscPluginFactoryContext<ITtscLintPluginConfig>): ITtscPlugin;
3
+ type TtscPluginDescriptor = {
4
+ name: string;
5
+ source: string;
6
+ stage?: "check" | "transform";
7
+ };
8
+ type TtscPluginFactoryContext<TConfig> = {
9
+ binary: string;
10
+ cwd: string;
11
+ plugin: TConfig;
12
+ projectRoot: string;
13
+ tsconfig: string;
14
+ };
15
+ export default function createTtscPlugin(_context: TtscPluginFactoryContext<ITtscLintPluginConfig>): TtscPluginDescriptor;
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,0DAA6B;AAK7B,qDAAmC;AAEnC,0BACE,QAA0D;IAE1D,OAAO;QACL,IAAI,EAAE,YAAY;QAClB,MAAM,EAAE,mBAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC;QAC/C,KAAK,EAAE,OAAO;KACf,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,0DAA6B;AAI7B,qDAAmC;AAgBnC,0BACE,QAAyD;IAEzD,OAAO;QACL,IAAI,EAAE,YAAY;QAClB,MAAM,EAAE,mBAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC;QAC/C,KAAK,EAAE,OAAO;KACf,CAAC;AACJ,CAAC"}
@@ -1,7 +1,10 @@
1
- import type { ITtscProjectPluginConfig } from "ttsc";
2
1
  import type { TtscLintConfig } from "./TtscLintConfig";
3
2
  /** `compilerOptions.plugins[]` entry shape consumed by `@ttsc/lint`. */
4
- export interface ITtscLintPluginConfig extends ITtscProjectPluginConfig {
3
+ export interface ITtscLintPluginConfig {
4
+ /** Set to `false` to keep the entry while disabling this plugin. */
5
+ enabled?: boolean;
6
+ /** Plugin module specifier. */
7
+ transform?: string;
5
8
  /**
6
9
  * Inline rule map or path to a standalone lint config file.
7
10
  *
@@ -10,4 +13,6 @@ export interface ITtscLintPluginConfig extends ITtscProjectPluginConfig {
10
13
  * directory and may point at JSON, JavaScript, or TypeScript config files.
11
14
  */
12
15
  config?: string | TtscLintConfig;
16
+ /** Extra plugin-owned fields are passed through unchanged. */
17
+ [key: string]: unknown;
13
18
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttsc/lint",
3
- "version": "0.8.1",
3
+ "version": "0.10.0",
4
4
  "description": "Reference ttsc plugin: ESLint-style lint rules hosted in the same Program/Checker as the type-check pass.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -9,10 +9,6 @@
9
9
  "types": "./lib/index.d.ts",
10
10
  "default": "./lib/index.js"
11
11
  },
12
- "./config": {
13
- "types": "./lib/config.d.ts",
14
- "default": "./lib/config.js"
15
- },
16
12
  "./package.json": "./package.json"
17
13
  },
18
14
  "keywords": [
@@ -22,6 +18,11 @@
22
18
  "typescript",
23
19
  "tsgo"
24
20
  ],
21
+ "ttsc": {
22
+ "plugin": {
23
+ "transform": "@ttsc/lint"
24
+ }
25
+ },
25
26
  "files": [
26
27
  "README.md",
27
28
  "lib",
@@ -30,10 +31,10 @@
30
31
  "plugin"
31
32
  ],
32
33
  "devDependencies": {
33
- "@typescript/native-preview": "7.0.0-dev.20260506.1",
34
+ "@typescript/native-preview": "7.0.0-dev.20260510.1",
34
35
  "@types/node": "^25.3.0",
35
36
  "rimraf": "^6.1.2",
36
- "ttsc": "0.8.1"
37
+ "ttsc": "0.10.0"
37
38
  },
38
39
  "repository": {
39
40
  "type": "git",
@@ -46,7 +47,6 @@
46
47
  },
47
48
  "homepage": "https://github.com/samchon/ttsc/tree/master/packages/lint#readme",
48
49
  "scripts": {
49
- "build": "rimraf lib && tsgo",
50
- "test": "pnpm run build && pnpm --dir ../../tests/lint start"
50
+ "build": "rimraf lib && tsgo"
51
51
  }
52
52
  }
package/plugin/compile.go CHANGED
@@ -329,19 +329,14 @@ func filterKnownFlags(args []string, known map[string]bool) []string {
329
329
  func collectDiagnostics(prog *program, engine *Engine) ([]*shimast.Diagnostic, []*shimdw.LintDiagnostic, bool, error) {
330
330
  astDiags := prog.programDiagnostics()
331
331
  files := prog.userSourceFiles()
332
- if externalDiags, ran, err := runExternalESLintDiagnostics(engine.config, prog.cwd, files); err != nil {
333
- return nil, nil, false, err
334
- } else if ran {
335
- return astDiags, externalDiags, true, nil
336
- }
337
332
  findings := engine.Run(files, prog.checker)
338
- lintDiags := make([]*shimdw.LintDiagnostic, 0, len(findings))
333
+ nativeDiags := make([]*shimdw.LintDiagnostic, 0, len(findings))
339
334
  for _, finding := range findings {
340
335
  category := shimdw.LintCategoryError
341
336
  if finding.Severity == SeverityWarn {
342
337
  category = shimdw.LintCategoryWarning
343
338
  }
344
- lintDiags = append(lintDiags, shimdw.NewLintDiagnostic(
339
+ nativeDiags = append(nativeDiags, shimdw.NewLintDiagnostic(
345
340
  finding.File,
346
341
  finding.Pos,
347
342
  finding.End,
@@ -350,7 +345,58 @@ func collectDiagnostics(prog *program, engine *Engine) ([]*shimast.Diagnostic, [
350
345
  fmt.Sprintf("[%s] %s", finding.Rule, finding.Message),
351
346
  ))
352
347
  }
353
- return astDiags, lintDiags, false, nil
348
+ if externalDiags, ran, err := runExternalESLintDiagnostics(engine.config, prog.cwd, files); err != nil {
349
+ return nil, nil, false, err
350
+ } else if ran {
351
+ return astDiags, mergeNativeAndExternalDiagnostics(nativeDiags, externalDiags), true, nil
352
+ }
353
+ return astDiags, nativeDiags, false, nil
354
+ }
355
+
356
+ func mergeNativeAndExternalDiagnostics(nativeDiags, externalDiags []*shimdw.LintDiagnostic) []*shimdw.LintDiagnostic {
357
+ if len(nativeDiags) == 0 {
358
+ return externalDiags
359
+ }
360
+ if len(externalDiags) == 0 {
361
+ return nativeDiags
362
+ }
363
+ externalRules := make(map[string]struct{})
364
+ for _, diag := range externalDiags {
365
+ if rule := canonicalLintRule(lintDiagnosticRule(diag)); rule != "" {
366
+ externalRules[rule] = struct{}{}
367
+ }
368
+ }
369
+ out := make([]*shimdw.LintDiagnostic, 0, len(nativeDiags)+len(externalDiags))
370
+ for _, diag := range nativeDiags {
371
+ rule := canonicalLintRule(lintDiagnosticRule(diag))
372
+ if _, exists := externalRules[rule]; rule != "" && exists {
373
+ continue
374
+ }
375
+ out = append(out, diag)
376
+ }
377
+ return append(out, externalDiags...)
378
+ }
379
+
380
+ func lintDiagnosticRule(diag *shimdw.LintDiagnostic) string {
381
+ if diag == nil {
382
+ return ""
383
+ }
384
+ message := diag.Message()
385
+ if !strings.HasPrefix(message, "[") {
386
+ return ""
387
+ }
388
+ end := strings.Index(message, "]")
389
+ if end <= 1 {
390
+ return ""
391
+ }
392
+ return message[1:end]
393
+ }
394
+
395
+ func canonicalLintRule(rule string) string {
396
+ rule = strings.TrimSpace(rule)
397
+ rule = strings.TrimPrefix(rule, "@typescript-eslint/")
398
+ rule = strings.TrimPrefix(rule, "typescript-eslint/")
399
+ return rule
354
400
  }
355
401
 
356
402
  // RuleCode hashes a rule name into a stable, positive int32 so the
package/plugin/config.go CHANGED
@@ -53,15 +53,12 @@ func ParsePlugins(text string) ([]PluginEntry, error) {
53
53
  return entries, nil
54
54
  }
55
55
 
56
- // FindLintEntry returns the lint entry only when it is the first active
57
- // plugin. Linting after a source-transforming plugin would inspect mutated
58
- // source, which is not a meaningful user-code lint result.
56
+ // FindLintEntry returns the active lint entry. ttsc orders check plugins before
57
+ // transform plugins before invoking native sidecars, so lint inspects authored
58
+ // source even when transform plugins are also configured.
59
59
  func FindLintEntry(entries []PluginEntry) (*PluginEntry, error) {
60
60
  for i := range entries {
61
61
  if entries[i].Name == "@ttsc/lint" {
62
- if i != 0 {
63
- return nil, fmt.Errorf("@ttsc/lint must be the first active compilerOptions.plugins entry")
64
- }
65
62
  return &entries[i], nil
66
63
  }
67
64
  }
@@ -529,12 +526,12 @@ func LoadConfigResolver(entry *PluginEntry, cwd, tsconfigPath string) (RuleResol
529
526
 
530
527
  value, ok := inline["config"]
531
528
  if !ok {
532
- discovered, err := findESLintConfigFile(cwd, tsconfigPath)
529
+ discovered, err := findLintConfigFile(cwd, tsconfigPath)
533
530
  if err != nil {
534
531
  return nil, err
535
532
  }
536
533
  if discovered == "" {
537
- return RuleConfig{}, nil
534
+ return nil, fmt.Errorf("@ttsc/lint: \"config\" is required when no lint.config.*, ttsc-lint.config.*, or supported eslint.config.* file can be discovered")
538
535
  }
539
536
  return loadExternalConfigResolver(discovered)
540
537
  }
@@ -565,18 +562,25 @@ func loadExternalConfigResolver(location string) (RuleResolver, error) {
565
562
  return store, nil
566
563
  }
567
564
 
568
- func findESLintConfigFile(cwd, tsconfigPath string) (string, error) {
569
- dir := cwd
570
- if tsconfigPath != "" {
571
- resolvedTsconfig := tsconfigPath
572
- if !filepath.IsAbs(resolvedTsconfig) {
573
- resolvedTsconfig = filepath.Join(cwd, resolvedTsconfig)
574
- }
575
- dir = filepath.Dir(resolvedTsconfig)
576
- }
565
+ func findLintConfigFile(cwd, tsconfigPath string) (string, error) {
566
+ dir := discoveryConfigBaseDir(cwd, tsconfigPath)
577
567
  for {
578
568
  matches := make([]string, 0, 1)
579
569
  for _, name := range []string{
570
+ "lint.config.json",
571
+ "lint.config.js",
572
+ "lint.config.mjs",
573
+ "lint.config.cjs",
574
+ "lint.config.ts",
575
+ "lint.config.mts",
576
+ "lint.config.cts",
577
+ "ttsc-lint.config.json",
578
+ "ttsc-lint.config.js",
579
+ "ttsc-lint.config.mjs",
580
+ "ttsc-lint.config.cjs",
581
+ "ttsc-lint.config.ts",
582
+ "ttsc-lint.config.mts",
583
+ "ttsc-lint.config.cts",
580
584
  "eslint.config.js",
581
585
  "eslint.config.mjs",
582
586
  "eslint.config.cjs",
@@ -590,7 +594,7 @@ func findESLintConfigFile(cwd, tsconfigPath string) (string, error) {
590
594
  }
591
595
  }
592
596
  if len(matches) > 1 {
593
- return "", fmt.Errorf("@ttsc/lint: multiple eslint config files found in %s; set \"config\" explicitly", dir)
597
+ return "", fmt.Errorf("@ttsc/lint: multiple lint config files found in %s; set \"config\" explicitly", dir)
594
598
  }
595
599
  if len(matches) == 1 {
596
600
  return matches[0], nil
@@ -607,15 +611,29 @@ func resolveConfigFilePath(configPath, cwd, tsconfigPath string) string {
607
611
  if filepath.IsAbs(configPath) {
608
612
  return configPath
609
613
  }
610
- base := cwd
614
+ return filepath.Join(tsconfigBaseDir(cwd, tsconfigPath), configPath)
615
+ }
616
+
617
+ func discoveryConfigBaseDir(cwd, tsconfigPath string) string {
611
618
  if tsconfigPath != "" {
612
619
  resolvedTsconfig := tsconfigPath
613
620
  if !filepath.IsAbs(resolvedTsconfig) {
614
621
  resolvedTsconfig = filepath.Join(cwd, resolvedTsconfig)
615
622
  }
616
- base = filepath.Dir(resolvedTsconfig)
623
+ return filepath.Dir(resolvedTsconfig)
624
+ }
625
+ return cwd
626
+ }
627
+
628
+ func tsconfigBaseDir(cwd, tsconfigPath string) string {
629
+ if tsconfigPath == "" {
630
+ return cwd
631
+ }
632
+ resolvedTsconfig := tsconfigPath
633
+ if !filepath.IsAbs(resolvedTsconfig) {
634
+ resolvedTsconfig = filepath.Join(cwd, resolvedTsconfig)
617
635
  }
618
- return filepath.Join(base, configPath)
636
+ return filepath.Dir(resolvedTsconfig)
619
637
  }
620
638
 
621
639
  func loadConfigFile(location string) (any, error) {
package/src/index.ts CHANGED
@@ -1,13 +1,26 @@
1
1
  import path from "node:path";
2
- import type { ITtscPlugin, ITtscPluginFactoryContext } from "ttsc";
3
2
 
4
3
  import type { ITtscLintPluginConfig } from "./structures";
5
4
 
6
5
  export * from "./structures/index";
7
6
 
7
+ type TtscPluginDescriptor = {
8
+ name: string;
9
+ source: string;
10
+ stage?: "check" | "transform";
11
+ };
12
+
13
+ type TtscPluginFactoryContext<TConfig> = {
14
+ binary: string;
15
+ cwd: string;
16
+ plugin: TConfig;
17
+ projectRoot: string;
18
+ tsconfig: string;
19
+ };
20
+
8
21
  export default function createTtscPlugin(
9
- _context: ITtscPluginFactoryContext<ITtscLintPluginConfig>,
10
- ): ITtscPlugin {
22
+ _context: TtscPluginFactoryContext<ITtscLintPluginConfig>,
23
+ ): TtscPluginDescriptor {
11
24
  return {
12
25
  name: "@ttsc/lint",
13
26
  source: path.resolve(__dirname, "..", "plugin"),
@@ -1,9 +1,13 @@
1
- import type { ITtscProjectPluginConfig } from "ttsc";
2
-
3
1
  import type { TtscLintConfig } from "./TtscLintConfig";
4
2
 
5
3
  /** `compilerOptions.plugins[]` entry shape consumed by `@ttsc/lint`. */
6
- export interface ITtscLintPluginConfig extends ITtscProjectPluginConfig {
4
+ export interface ITtscLintPluginConfig {
5
+ /** Set to `false` to keep the entry while disabling this plugin. */
6
+ enabled?: boolean;
7
+
8
+ /** Plugin module specifier. */
9
+ transform?: string;
10
+
7
11
  /**
8
12
  * Inline rule map or path to a standalone lint config file.
9
13
  *
@@ -12,4 +16,7 @@ export interface ITtscLintPluginConfig extends ITtscProjectPluginConfig {
12
16
  * directory and may point at JSON, JavaScript, or TypeScript config files.
13
17
  */
14
18
  config?: string | TtscLintConfig;
19
+
20
+ /** Extra plugin-owned fields are passed through unchanged. */
21
+ [key: string]: unknown;
15
22
  }
package/lib/config.d.ts DELETED
@@ -1,3 +0,0 @@
1
- export type { TtscLintConfig } from "./structures/TtscLintConfig";
2
- export type { TtscLintRule } from "./structures/TtscLintRule";
3
- export type { TtscLintSeverity } from "./structures/TtscLintSeverity";
package/lib/config.js DELETED
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=config.js.map
package/lib/config.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":""}
package/src/config.ts DELETED
@@ -1,3 +0,0 @@
1
- export type { TtscLintConfig } from "./structures/TtscLintConfig";
2
- export type { TtscLintRule } from "./structures/TtscLintRule";
3
- export type { TtscLintSeverity } from "./structures/TtscLintSeverity";