@ttsc/lint 0.14.0-dev.20260528.1 → 0.14.0-dev.20260529.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +69 -76
  2. package/linthost/lsp.go +149 -2
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -2,14 +2,9 @@
2
2
 
3
3
  ![banner of @ttsc/lint](https://ttsc.dev/og.jpg)
4
4
 
5
- [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/ttsc/blob/master/LICENSE)
6
- [![NPM Version](https://img.shields.io/npm/v/@ttsc/lint.svg)](https://www.npmjs.com/package/@ttsc/lint)
7
- [![NPM Downloads](https://img.shields.io/npm/dm/@ttsc/lint.svg)](https://www.npmjs.com/package/@ttsc/lint)
8
- [![Build Status](https://github.com/samchon/ttsc/workflows/test/badge.svg)](https://github.com/samchon/ttsc/actions?query=workflow%3Atest)
9
- [![Guide Documents](https://img.shields.io/badge/Guide-Documents-forestgreen)](https://ttsc.dev/docs)
10
- [![Discord Badge](https://img.shields.io/badge/discord-samchon-d91965?style=flat&labelColor=5866f2&logo=discord&logoColor=white&link=https://discord.gg/E94XhzrUCZ)](https://discord.gg/E94XhzrUCZ)
5
+ [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/ttsc/blob/master/LICENSE) [![NPM Version](https://img.shields.io/npm/v/@ttsc/lint.svg)](https://www.npmjs.com/package/@ttsc/lint) [![NPM Downloads](https://img.shields.io/npm/dm/@ttsc/lint.svg)](https://www.npmjs.com/package/@ttsc/lint) [![Build Status](https://github.com/samchon/ttsc/workflows/test/badge.svg)](https://github.com/samchon/ttsc/actions?query=workflow%3Atest) [![Guide Documents](https://img.shields.io/badge/Guide-Documents-forestgreen)](https://ttsc.dev/docs) [![Discord Badge](https://img.shields.io/badge/discord-samchon-d91965?style=flat&labelColor=5866f2&logo=discord&logoColor=white&link=https://discord.gg/E94XhzrUCZ)](https://discord.gg/E94XhzrUCZ)
11
6
 
12
- A linter and formatter. Co-protagonist of the [`ttsc`](https://ttsc.dev) toolchain paired with `ttsc`, it replaces `eslint` and `prettier`.
7
+ A linter and formatter. Co-protagonist of the [`ttsc`](https://ttsc.dev) toolchain, paired with `ttsc`, it replaces `eslint` and `prettier`.
13
8
 
14
9
  720+ rules across 21 families. Lint violations surface as `error TSxxxxx` from a single compile pass; the formatter applies via `ttsc format`.
15
10
 
@@ -86,7 +81,7 @@ npx ttsx src/index.ts
86
81
 
87
82
  Errors fail the command; warnings print without affecting the exit code. Under `ttsx`, errors stop the program before your entrypoint runs.
88
83
 
89
- `ttsc fix` applies every autofix the enabled rules offer lint and format together writes results back to disk, then re-runs type-check + lint. `ttsc format` runs the format rule set through the same dataflow.
84
+ `ttsc fix` applies every autofix the enabled rules offer, lint and format together. Writes results back to disk, then re-runs type-check + lint. `ttsc format` runs the format rule set through the same dataflow.
90
85
 
91
86
  ```bash
92
87
  npx ttsc fix
@@ -97,7 +92,7 @@ npx ttsc format
97
92
 
98
93
  ## Format
99
94
 
100
- Configure the formatter through the `format` block in `lint.config.ts`. Keys mirror `.prettierrc`; the presence of the block even empty `format: {}` enables the always-on format rules at Prettier defaults so `ttsc format` rewrites your source to match.
95
+ Configure the formatter through the `format` block in `lint.config.ts`. Keys mirror `.prettierrc`; the presence of the block, even empty `format: {}`, enables the always-on format rules at Prettier defaults so `ttsc format` rewrites your source to match.
101
96
 
102
97
  ```ts
103
98
  // lint.config.ts
@@ -115,13 +110,13 @@ export default {
115
110
  } satisfies ITtscLintConfig;
116
111
  ```
117
112
 
118
- `ttsc check` does **not** fail on formatting by default it surfaces format diagnostics only when you opt in with `format.severity`. `ttsc format` runs the active format rules across the project and writes results to disk regardless of `severity`.
113
+ `ttsc check` does **not** fail on formatting by default. It surfaces format diagnostics only when you opt in with `format.severity`. `ttsc format` runs the active format rules across the project and writes results to disk regardless of `severity`.
119
114
 
120
115
  Each `format` config key activates one rule:
121
116
 
122
117
  | Config key | Rule | Effect |
123
118
  | --- | --- | --- |
124
- | `severity` (default `"off"`) | applies to every format rule | Sets the check-time diagnostic level. Does not gate `ttsc format` that runs all active rules. |
119
+ | `severity` (default `"off"`) | applies to every format rule | Sets the check-time diagnostic level. Does not gate `ttsc format`. That runs all active rules. |
125
120
  | `semi` | `format/semi` | Insert trailing semicolons on ASI-terminated statements. |
126
121
  | `singleQuote` | `format/quotes` | Convert quoted strings to the preferred quote style. |
127
122
  | `trailingComma` | `format/trailing-comma` | Add trailing commas to multi-line lists. |
@@ -129,9 +124,9 @@ Each `format` config key activates one rule:
129
124
  | `importOrder` (opt-in) | `format/sort-imports` | Group external/relative imports and alphabetize each group + its specifiers. |
130
125
  | `jsdoc` (opt-in) | `format/jsdoc` | Normalize JSDoc blocks toward [prettier-plugin-jsdoc](https://github.com/hosseinmd/prettier-plugin-jsdoc). |
131
126
 
132
- `format/sort-imports` and `format/jsdoc` are **opt-in** they only activate when you set `importOrder` or `jsdoc`. Every other format rule turns on automatically as soon as the `format` block is present.
127
+ `format/sort-imports` and `format/jsdoc` are **opt-in**. They only activate when you set `importOrder` or `jsdoc`. Every other format rule turns on automatically as soon as the `format` block is present.
133
128
 
134
- To override a single format rule, drop a sibling `rules` entry `rules` wins on conflict:
129
+ To override a single format rule, drop a sibling `rules` entry, `rules` wins on conflict:
135
130
 
136
131
  ```ts
137
132
  export default {
@@ -156,21 +151,21 @@ export default {
156
151
  } satisfies ITtscLintConfig;
157
152
  ```
158
153
 
159
- Rule IDs use ESLint-style kebab-case and slash namespaces `no-var`, `react/jsx-key`, `testing-library/prefer-screen-queries`. The exported `ITtscLintRules` type is the intersection of family-specific interfaces such as `ITtscLintCoreRules`, `ITtscLintTypeScriptRules`, `ITtscLintReactRules`, and `ITtscLintVitestRules`, so users can type a whole config or a narrower family-shaped object.
154
+ Rule IDs use ESLint-style kebab-case and slash namespaces, `no-var`, `react/jsx-key`, `testing-library/prefer-screen-queries`. The exported `ITtscLintRules` type is the intersection of family-specific interfaces such as `ITtscLintCoreRules`, `ITtscLintTypeScriptRules`, `ITtscLintReactRules`, and `ITtscLintVitestRules`, so users can type a whole config or a narrower family-shaped object.
160
155
 
161
156
  Each rule below links to its TypeScript fixture under [`tests/test-lint/src/cases/`](https://github.com/samchon/ttsc/tree/master/tests/test-lint/src/cases).
162
157
 
163
158
  <!--
164
- AGENT INSTRUCTIONS adding a new rule family or a new rule.
159
+ AGENT INSTRUCTIONS, adding a new rule family or a new rule.
165
160
 
166
161
  Family section shape (one `### <Family display name>` heading per family, alphabetical
167
162
  by display name):
168
163
 
169
164
  ### <Family display name>
170
165
 
171
- <One-sentence summary of what this family covers the "what".>
166
+ <One-sentence summary of what this family covers, the "what".>
172
167
 
173
- <One short paragraph elaborating the "why" / scope notes / known limits.>
168
+ <One short paragraph elaborating, the "why" / scope notes / known limits.>
174
169
 
175
170
  Source: [`<upstream-package>`](https://github.com/<org>/<repo>), [optional second source](https://…).
176
171
 
@@ -178,7 +173,7 @@ by display name):
178
173
 
179
174
  Rules:
180
175
 
181
- - Bullet shape is `- [\`<rule-id>\`](url): description.` colon as separator, lowercase
176
+ - Bullet shape is `- [\`<rule-id>\`](url): description.`: colon as separator, lowercase
182
177
  description, ending in a period. No em-dash separator. Bullets sort alphabetically
183
178
  by rule id within the family.
184
179
  - The fixture path is `tests/test-lint/src/cases/<rule-id>.ts` for core rules,
@@ -196,17 +191,16 @@ Rules:
196
191
  joined the family list.
197
192
  -->
198
193
 
199
-
200
194
  ### ESLint core
201
195
 
202
- Generic ESLint-compatible rules that apply to both JavaScript and TypeScript source. Every rule listed here corresponds 1-to-1 with an ESLint core rule of the same kebab-case id, so projects migrating from ESLint can paste their rule severities into `lint.config.ts` without renaming anything. TypeScript-only rules and `@typescript-eslint` extensions live under `typescript/*` in [TypeScript](#typescript) `@ttsc/lint` does not accept legacy bare names or `@typescript-eslint/*` aliases for those.
196
+ Generic ESLint-compatible rules that apply to both JavaScript and TypeScript source. Every rule listed here corresponds 1-to-1 with an ESLint core rule of the same kebab-case id, so projects migrating from ESLint can paste their rule severities into `lint.config.ts` without renaming anything. TypeScript-only rules and `@typescript-eslint` extensions live under `typescript/*` in [TypeScript](#typescript), `@ttsc/lint` does not accept legacy bare names or `@typescript-eslint/*` aliases for those.
203
197
 
204
198
  Source: [ESLint core rules](https://eslint.org/docs/latest/rules/).
205
199
 
206
- - [`camelcase`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/camelcase.ts): reject identifier declarations that aren't camelCase or PascalCase snake_case bindings are flagged.
200
+ - [`camelcase`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/camelcase.ts): reject identifier declarations that aren't camelCase or PascalCase, snake_case bindings are flagged.
207
201
  - [`complexity`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/complexity.ts): reject function bodies whose cyclomatic complexity exceeds twenty (default ESLint threshold).
208
202
  - [`consistent-return`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/consistent-return.ts): reject functions where some `return` statements return a value and others fall through without one.
209
- - [`curly`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/curly.ts): require block statements for every `if`, `else`, `while`, `for`, and `do` body reject the single-statement shorthand.
203
+ - [`curly`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/curly.ts): require block statements for every `if`, `else`, `while`, `for`, and `do` body. Reject the single-statement shorthand.
210
204
  - [`default-case`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/default-case.ts): require `switch` statements to include a `default` clause.
211
205
  - [`default-case-last`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/default-case-last.ts): require the `default` clause of a `switch` statement to appear last.
212
206
  - [`default-param-last`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/default-param-last.ts): keeps parameters with default values at the end of the list.
@@ -313,7 +307,7 @@ Source: [ESLint core rules](https://eslint.org/docs/latest/rules/).
313
307
  - [`no-undef-init`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-undef-init.ts): rejects initializing to `undefined`.
314
308
  - [`no-undefined`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-undefined.ts): rejects the global `undefined` identifier.
315
309
  - [`no-unneeded-ternary`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-unneeded-ternary.ts): rejects redundant ternary expressions.
316
- - [`no-unreachable`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-unreachable.ts): reject statements that follow an unconditional `return`, `throw`, `break`, or `continue` in the same block control flow has already left the block, so any later statement is dead code.
310
+ - [`no-unreachable`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-unreachable.ts): reject statements that follow an unconditional `return`, `throw`, `break`, or `continue` in the same block, control flow has already left the block, so any later statement is dead code.
317
311
  - [`no-unsafe-finally`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-unsafe-finally.ts): rejects control flow from `finally`.
318
312
  - [`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.
319
313
  - [`no-unsafe-optional-chaining`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-unsafe-optional-chaining.ts): reject member access or call expressions that chain off an optional chain without continuing the chain.
@@ -332,16 +326,16 @@ Source: [ESLint core rules](https://eslint.org/docs/latest/rules/).
332
326
  - [`no-with`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-with.ts): rejects `with` statements.
333
327
  - [`object-shorthand`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/object-shorthand.ts): requires object property shorthand where possible.
334
328
  - [`operator-assignment`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/operator-assignment.ts): prefers compound assignment operators.
335
- - [`prefer-arrow-callback`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-arrow-callback.ts): reject `function() { ... }` expressions passed as callback arguments prefer the arrow form.
329
+ - [`prefer-arrow-callback`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-arrow-callback.ts): reject `function() { ... }` expressions passed as callback arguments. Prefer the arrow form.
336
330
  - [`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.
337
331
  - [`prefer-destructuring`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-destructuring.ts): reject single-property and single-index variable declarations (`const a = obj.a`, `const x = arr[0]`) that destructuring would replace verbatim.
338
332
  - [`prefer-exponentiation-operator`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-exponentiation-operator.ts): prefers `**` over `Math.pow`.
339
333
  - [`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.
340
- - [`prefer-named-capture-group`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-named-capture-group.ts): reject regex literals with unnamed capturing groups `(...)` prefer named groups `(?<name>...)`.
334
+ - [`prefer-named-capture-group`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-named-capture-group.ts): reject regex literals with unnamed capturing groups `(...)`. Prefer named groups `(?<name>...)`.
341
335
  - [`prefer-numeric-literals`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-numeric-literals.ts): prefer ES2015+ numeric literal forms (`0b…`, `0o…`, `0x…`) over `parseInt(string, 2 | 8 | 16)`.
342
336
  - [`prefer-object-has-own`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-object-has-own.ts): prefer `Object.hasOwn(obj, key)` over `Object.prototype.hasOwnProperty.call(obj, key)`.
343
337
  - [`prefer-object-spread`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-object-spread.ts): prefer object-spread `{ ...a, ...b }` over `Object.assign({}, a, b)`.
344
- - [`prefer-rest-params`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-rest-params.ts): reject reading from `arguments` in a non-arrow function body prefer the ES2015 rest-parameter form `(...args)`.
338
+ - [`prefer-rest-params`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-rest-params.ts): reject reading from `arguments` in a non-arrow function body. Prefer the ES2015 rest-parameter form `(...args)`.
345
339
  - [`prefer-spread`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-spread.ts): prefers spread arguments over `.apply`.
346
340
  - [`prefer-template`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-template.ts): prefers template literals over string concatenation.
347
341
  - [`radix`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/radix.ts): requires a radix argument for `parseInt`.
@@ -378,7 +372,7 @@ Source: [`typescript-eslint`](https://github.com/typescript-eslint/typescript-es
378
372
  - [`typescript/no-array-for-each`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-array-for-each.ts): prefer `for ... of` over `Array.prototype.forEach()`.
379
373
  - [`typescript/no-base-to-string`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-base-to-string.ts): rejects string coercion of values whose `toString` resolves to the default `Object.prototype.toString` (type-aware).
380
374
  - [`typescript/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.
381
- - [`typescript/no-confusing-void-expression`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-confusing-void-expression.ts): reject `void X` expressions used in any position where the surrounding context expects a value initializer, call argument, `return` operand, conditional, binary, or ternary subexpression.
375
+ - [`typescript/no-confusing-void-expression`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-confusing-void-expression.ts): reject `void X` expressions used in any position where the surrounding context expects a value, initializer, call argument, `return` operand, conditional, binary, or ternary subexpression.
382
376
  - [`typescript/no-deprecated`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-deprecated.ts): reject references to declarations annotated `@deprecated` in their JSDoc, with the deprecation comment surfaced at the reference site (type-aware).
383
377
  - [`typescript/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.
384
378
  - [`typescript/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.
@@ -387,13 +381,13 @@ Source: [`typescript-eslint`](https://github.com/typescript-eslint/typescript-es
387
381
  - [`typescript/no-explicit-any`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-explicit-any.ts): rejects explicit `any`.
388
382
  - [`typescript/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.
389
383
  - [`typescript/no-extraneous-class`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-extraneous-class.ts): reject classes that exist purely as a namespace for static members or that are entirely empty.
390
- - [`typescript/no-floating-promises`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-floating-promises.ts): reject Promise-typed expressions whose result is discarded most often a bare `getPromise();` expression statement.
384
+ - [`typescript/no-floating-promises`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-floating-promises.ts): reject Promise-typed expressions whose result is discarded, most often a bare `getPromise();` expression statement.
391
385
  - [`typescript/no-for-in-array`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-for-in-array.ts): reject `for (const k in arr)` where `arr` is statically typed as an array or tuple.
392
386
  - [`typescript/no-import-type-side-effects`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-import-type-side-effects/violation.ts): hoists inline `type` modifiers into a single `import type` declaration.
393
387
  - [`typescript/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.
394
388
  - [`typescript/no-invalid-void-type`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-invalid-void-type.ts): reject `void` used as anything other than a function return type.
395
389
  - [`typescript/no-magic-numbers`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-magic-numbers.ts): typeScript-aware extension of `no-magic-numbers` that additionally ignores enum member values.
396
- - [`typescript/no-meaningless-void-operator`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-meaningless-void-operator.ts): reject `void X` where `X` is already statically typed `void` the operator adds nothing because the operand already evaluates to `undefined` (type-aware).
390
+ - [`typescript/no-meaningless-void-operator`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-meaningless-void-operator.ts): reject `void X` where `X` is already statically typed `void`, the operator adds nothing because the operand already evaluates to `undefined` (type-aware).
397
391
  - [`typescript/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.
398
392
  - [`typescript/no-misused-promises`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-misused-promises.ts): reject Promise values supplied where a non-Promise was expected.
399
393
  - [`typescript/no-misused-spread`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-misused-spread.ts): reject spread expressions whose operand is syntactically wrong for the surrounding context.
@@ -402,33 +396,33 @@ Source: [`typescript-eslint`](https://github.com/typescript-eslint/typescript-es
402
396
  - [`typescript/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 `??`.
403
397
  - [`typescript/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.
404
398
  - [`typescript/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.
405
- - [`typescript/no-redundant-type-constituents`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-redundant-type-constituents.ts): reject union and intersection type constituents that the type system absorbs anyway `string | any` collapses to `any`, `T & never` collapses to `never`, `T & unknown` collapses to `T`, and repeated constituents add nothing.
399
+ - [`typescript/no-redundant-type-constituents`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-redundant-type-constituents.ts): reject union and intersection type constituents that the type system absorbs anyway, `string | any` collapses to `any`, `T & never` collapses to `never`, `T & unknown` collapses to `T`, and repeated constituents add nothing.
406
400
  - [`typescript/no-require-imports`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-require-imports.ts): rejects CommonJS `require` imports.
407
- - [`typescript/no-restricted-types`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-restricted-types.ts): reject specific type-reference names that are almost always a mistake by default the global wrapper types `Object`, `Function`, `Number`, `String`, and `Boolean`.
401
+ - [`typescript/no-restricted-types`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-restricted-types.ts): reject specific type-reference names that are almost always a mistake, by default the global wrapper types `Object`, `Function`, `Number`, `String`, and `Boolean`.
408
402
  - [`typescript/no-this-alias`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-this-alias.ts): rejects aliasing `this` to locals.
409
- - [`typescript/no-unnecessary-boolean-literal-compare`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unnecessary-boolean-literal-compare.ts): reject direct comparison of a boolean-typed value with `true` / `false` literals `x === true` is just `x`, `x !== false` is just `x`.
410
- - [`typescript/no-unnecessary-condition`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unnecessary-condition.ts): reject conditions whose static type proves the runtime truthiness is fixed `if ({})`, `if (null)`, `while ("")`, `0 && f()` (type-aware).
403
+ - [`typescript/no-unnecessary-boolean-literal-compare`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unnecessary-boolean-literal-compare.ts): reject direct comparison of a boolean-typed value with `true` / `false` literals, `x === true` is just `x`, `x !== false` is just `x`.
404
+ - [`typescript/no-unnecessary-condition`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unnecessary-condition.ts): reject conditions whose static type proves the runtime truthiness is fixed, `if ({})`, `if (null)`, `while ("")`, `0 && f()` (type-aware).
411
405
  - [`typescript/no-unnecessary-parameter-property-assignment`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-unnecessary-parameter-property-assignment.ts): rejects constructor assignments already handled by parameter properties.
412
406
  - [`typescript/no-unnecessary-qualifier`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unnecessary-qualifier.ts): reject namespace/enum qualifiers that the surrounding scope makes unnecessary (type-aware).
413
- - [`typescript/no-unnecessary-template-expression`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unnecessary-template-expression.ts): reject template literals that collapse to a regular string `` `${"abc"}` ``, `` `${name}` `` around a string-typed value, or a plain `` `abc` `` with no escaped backticks (type-aware).
414
- - [`typescript/no-unnecessary-type-arguments`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unnecessary-type-arguments.ts): reject `Foo<DefaultT>` calls where the supplied generic argument is the same as the parameter's default the argument adds nothing (type-aware).
415
- - [`typescript/no-unnecessary-type-assertion`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unnecessary-type-assertion.ts): reject `x as T`, `<T>x`, and `x!` assertions whose target type is the same as `x`'s already-known static type the assertion adds nothing (type-aware).
407
+ - [`typescript/no-unnecessary-template-expression`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unnecessary-template-expression.ts): reject template literals that collapse to a regular string, `` `${"abc"}` ``, `` `${name}` `` around a string-typed value, or a plain `` `abc` `` with no escaped backticks (type-aware).
408
+ - [`typescript/no-unnecessary-type-arguments`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unnecessary-type-arguments.ts): reject `Foo<DefaultT>` calls where the supplied generic argument is the same as the parameter's default, the argument adds nothing (type-aware).
409
+ - [`typescript/no-unnecessary-type-assertion`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unnecessary-type-assertion.ts): reject `x as T`, `<T>x`, and `x!` assertions whose target type is the same as `x`'s already-known static type, the assertion adds nothing (type-aware).
416
410
  - [`typescript/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.
417
411
  - [`typescript/no-unsafe-argument`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unsafe-argument.ts): reject passing an `any`-typed value to a parameter whose declared type is concrete (type-aware).
418
412
  - [`typescript/no-unsafe-assignment`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unsafe-assignment.ts): reject assigning an `any`-typed value to a variable, parameter, or property whose declared type is concrete (type-aware).
419
413
  - [`typescript/no-unsafe-call`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unsafe-call.ts): reject calling a value whose static type is `any` (type-aware).
420
414
  - [`typescript/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.
421
- - [`typescript/no-unsafe-enum-comparison`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unsafe-enum-comparison.ts): reject `==` / `===` / `!=` / `!==` comparisons between an enum-typed value and a plain `number` or `string` of the same widened primitive the comparison silently accepts unrelated enums and raw literals that happen to share the underlying primitive (type-aware).
415
+ - [`typescript/no-unsafe-enum-comparison`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unsafe-enum-comparison.ts): reject `==` / `===` / `!=` / `!==` comparisons between an enum-typed value and a plain `number` or `string` of the same widened primitive, the comparison silently accepts unrelated enums and raw literals that happen to share the underlying primitive (type-aware).
422
416
  - [`typescript/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.
423
417
  - [`typescript/no-unsafe-member-access`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unsafe-member-access.ts): reject member access on a value whose static type is `any` (type-aware).
424
- - [`typescript/no-unsafe-return`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unsafe-return.ts): reject a `return` expression whose static type is `any` from a function whose declared return type is a concrete (non-`any` / non-`unknown` / non-`void`) shape the `any` leaks past the type boundary and disables every downstream check on the returned value (type-aware).
425
- - [`typescript/no-unsafe-unary-minus`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unsafe-unary-minus.ts): reject the unary `-` operator applied to an operand whose static type is not number-like or bigint-like `-x` silently coerces strings, objects, and other shapes via `Number(x)` and almost always indicates a bug (type-aware).
418
+ - [`typescript/no-unsafe-return`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unsafe-return.ts): reject a `return` expression whose static type is `any` from a function whose declared return type is a concrete (non-`any` / non-`unknown` / non-`void`) shape, the `any` leaks past the type boundary and disables every downstream check on the returned value (type-aware).
419
+ - [`typescript/no-unsafe-unary-minus`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-unsafe-unary-minus.ts): reject the unary `-` operator applied to an operand whose static type is not number-like or bigint-like, `-x` silently coerces strings, objects, and other shapes via `Number(x)` and almost always indicates a bug (type-aware).
426
420
  - [`typescript/no-useless-constructor`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-no-useless-constructor.ts): typeScript-aware extension of `no-useless-constructor` that tolerates a constructor existing solely to expose parameter properties.
427
421
  - [`typescript/no-useless-empty-export`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/no-useless-empty-export.ts): rejects redundant empty `export {}` declarations in module files.
428
422
  - [`typescript/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`.
429
- - [`typescript/non-nullable-type-assertion-style`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/non-nullable-type-assertion-style.ts): reject `x as Foo` assertions whose target type is the non-nullable version of `x`'s static type replace with the shorter `x!` non-null assertion.
430
- - [`typescript/only-throw-error`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/only-throw-error.ts): reject `throw X` where `X` is statically known not to derive from `Error` string literals, numbers, plain object literals, and the like.
431
- - [`typescript/parameter-properties`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-parameter-properties.ts): reject TypeScript parameter-property constructors (`constructor(public foo: T)`) prefer plain field declarations so the class shape is visible from the member list instead of buried inside the constructor parameter list.
423
+ - [`typescript/non-nullable-type-assertion-style`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/non-nullable-type-assertion-style.ts): reject `x as Foo` assertions whose target type is the non-nullable version of `x`'s static type. Replace with the shorter `x!` non-null assertion.
424
+ - [`typescript/only-throw-error`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/only-throw-error.ts): reject `throw X` where `X` is statically known not to derive from `Error`, string literals, numbers, plain object literals, and the like.
425
+ - [`typescript/parameter-properties`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-parameter-properties.ts): reject TypeScript parameter-property constructors (`constructor(public foo: T)`). Prefer plain field declarations so the class shape is visible from the member list instead of buried inside the constructor parameter list.
432
426
  - [`typescript/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.
433
427
  - [`typescript/prefer-enum-initializers`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/prefer-enum-initializers.ts): requires explicit enum member initializers.
434
428
  - [`typescript/prefer-find`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-prefer-find.ts): prefer `array.find(predicate)` over `array.filter(predicate)[0]` / `.shift()` when only the first match is needed.
@@ -438,18 +432,18 @@ Source: [`typescript-eslint`](https://github.com/typescript-eslint/typescript-es
438
432
  - [`typescript/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.
439
433
  - [`typescript/prefer-nullish-coalescing`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-prefer-nullish-coalescing.ts): prefer `??` over `||` (and `??=` over `||=`, and `??` over the ternary `x ? x : y`) when the intent is to default `null` / `undefined`.
440
434
  - [`typescript/prefer-optional-chain`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-prefer-optional-chain.ts): prefer an optional chain (`a?.b?.c`) over chained boolean guards such as `a && a.b && a.b.c` or `a != null && a.b`.
441
- - [`typescript/prefer-promise-reject-errors`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-prefer-promise-reject-errors.ts): reject `Promise.reject(value)` where `value` is statically known not to derive from `Error` type-aware analog of `only-throw-error` for the rejection side of the promise contract.
435
+ - [`typescript/prefer-promise-reject-errors`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-prefer-promise-reject-errors.ts): reject `Promise.reject(value)` where `value` is statically known not to derive from `Error`, type-aware analog of `only-throw-error` for the rejection side of the promise contract.
442
436
  - [`typescript/prefer-readonly`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-prefer-readonly.ts): reject private class fields that could carry `readonly`.
443
437
  - [`typescript/prefer-reduce-type-parameter`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-prefer-reduce-type-parameter.ts): prefer `arr.reduce<T>(..., initial)` over `arr.reduce(..., initial as T)` so the accumulator type is set on the call site instead of widened away inside the assertion (type-aware).
444
- - [`typescript/prefer-regexp-exec`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-prefer-regexp-exec.ts): prefer `regex.exec(str)` over `str.match(regex)` when the regex carries the `g` flag `.match` returns only the matched substrings and discards capture groups.
438
+ - [`typescript/prefer-regexp-exec`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-prefer-regexp-exec.ts): prefer `regex.exec(str)` over `str.match(regex)` when the regex carries the `g` flag, `.match` returns only the matched substrings and discards capture groups.
445
439
  - [`typescript/prefer-return-this-type`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-prefer-return-this-type.ts): prefer the explicit `this` return type for chainable methods so fluent subclasses preserve their concrete `this` instead of widening to the base.
446
440
  - [`typescript/prefer-string-starts-ends-with`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-prefer-string-starts-ends-with.ts): prefer `str.startsWith(p)` / `str.endsWith(p)` over `str.indexOf(p) === 0`, `str.indexOf(p, str.length - p.length) !== -1`, `str.lastIndexOf(p) === str.length - p.length`, and the anchored-regex `/^p/.test(str)` / `/p$/.test(str)` idioms (type-aware).
447
441
  - [`typescript/promise-function-async`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-promise-function-async.ts): require functions whose return type is `Promise<T>` to be declared with the `async` keyword so synchronous throws surface as a rejected Promise (type-aware).
448
- - [`typescript/related-getter-setter-pairs`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-related-getter-setter-pairs.ts): reject a `get` accessor whose declared return type does not match the parameter type of its companion `set` accessor on the same class readers should not observe a type the writer cannot accept (type-aware).
442
+ - [`typescript/related-getter-setter-pairs`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-related-getter-setter-pairs.ts): reject a `get` accessor whose declared return type does not match the parameter type of its companion `set` accessor on the same class, readers should not observe a type the writer cannot accept (type-aware).
449
443
  - [`typescript/require-array-sort-compare`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-require-array-sort-compare.ts): require `arr.sort()` and `arr.toSorted()` calls to pass an explicit `compareFunction`.
450
444
  - [`typescript/require-await`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/require-await.ts): reject `async` functions whose body contains no `await` expression.
451
445
  - [`typescript/restrict-plus-operands`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-restrict-plus-operands.ts): rejects `+` expressions whose operands are not both `number`, both `string`, or both `bigint` (type-aware).
452
- - [`typescript/restrict-template-expressions`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-restrict-template-expressions.ts): reject template-literal interpolations whose expression carries a type that does not stringify cleanly `${obj}` prints `"[object Object]"`, `${null}` prints `"null"`, and so on.
446
+ - [`typescript/restrict-template-expressions`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-restrict-template-expressions.ts): reject template-literal interpolations whose expression carries a type that does not stringify cleanly, `${obj}` prints `"[object Object]"`, `${null}` prints `"null"`, and so on.
453
447
  - [`typescript/return-await`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/return-await.ts): reject `return promise` inside `try`, `catch`, or `finally`; require `return await promise`.
454
448
  - [`typescript/sort-type-constituents`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-sort-type-constituents.ts): sort the members of union (`A | B | C`) and intersection (`A & B & C`) types into a canonical order so reorderings don't show up as diffs.
455
449
  - [`typescript/strict-boolean-expressions`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/typescript-strict-boolean-expressions.ts): rejects non-boolean values used in a boolean context such as `if`, `&&`, `||`, or `!` (type-aware).
@@ -460,13 +454,13 @@ Source: [`typescript-eslint`](https://github.com/typescript-eslint/typescript-es
460
454
 
461
455
  ### React
462
456
 
463
- React TSX rules Hooks correctness, JSX safety, the React Compiler subset, and Fast Refresh export shape. Bundles rules from three upstream plugins under one `react/*` namespace, matching Oxlint's layout. Performance-only rules live in [React performance](#react-performance) because they are opt-in toggles rather than correctness checks.
457
+ React TSX rules, Hooks correctness, JSX safety, the React Compiler subset, and Fast Refresh export shape. Bundles rules from three upstream plugins under one `react/*` namespace, matching Oxlint's layout. Performance-only rules live in [React performance](#react-performance) because they are opt-in toggles rather than correctness checks.
464
458
 
465
459
  Source: [`eslint-plugin-react`](https://github.com/jsx-eslint/eslint-plugin-react), [`eslint-plugin-react-hooks`](https://github.com/facebook/react/tree/main/packages/eslint-plugin-react-hooks), [`eslint-plugin-react-refresh`](https://github.com/ArnaudBarre/eslint-plugin-react-refresh).
466
460
 
467
461
  - [`react/button-has-type`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/react-button-has-type.tsx): requires explicit valid `type` values on JSX `button` elements.
468
462
  - [`react/component-hook-factories`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/react-component-hook-factories.tsx): rejects nested component or Hook factories that call Hooks.
469
- - [`react/display-name`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/react-display-name.tsx): require components wrapped in `React.memo(...)` or `React.forwardRef(...)` to be named either by passing a named function, assigning the call to a named binding, or setting an explicit `displayName`.
463
+ - [`react/display-name`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/react-display-name.tsx): require components wrapped in `React.memo(...)` or `React.forwardRef(...)` to be named, either by passing a named function, assigning the call to a named binding, or setting an explicit `displayName`.
470
464
  - [`react/exhaustive-deps`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/react-exhaustive-deps.tsx): reports high-confidence missing identifier dependencies in `useEffect`, `useLayoutEffect`, `useInsertionEffect`, `useMemo`, and `useCallback`.
471
465
  - [`react/iframe-missing-sandbox`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/react-iframe-missing-sandbox.tsx): requires JSX `iframe` elements to include a sandbox attribute.
472
466
  - [`react/immutability`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/react-immutability.tsx): rejects local prop mutation inside components and Hooks.
@@ -475,7 +469,7 @@ Source: [`eslint-plugin-react`](https://github.com/jsx-eslint/eslint-plugin-reac
475
469
  - [`react/jsx-no-script-url`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/react-jsx-no-script-url.tsx): rejects `javascript:` URLs in JSX URL-like props.
476
470
  - [`react/jsx-no-target-blank`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/react-jsx-no-target-blank.tsx): reject `<a target="_blank">` (or any JSX element with `target="_blank"`) that does not also carry `rel="noreferrer"` (or `rel="noopener noreferrer"`).
477
471
  - [`react/jsx-no-undef`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/react-jsx-no-undef.tsx): reject JSX elements whose tag is an uppercase identifier with no value-level declaration anywhere in the source file.
478
- - [`react/jsx-no-useless-fragment`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/react-jsx-no-useless-fragment.tsx): reject JSX fragments that wrap exactly one element child or have no meaningful content the child (or nothing) can be returned directly.
472
+ - [`react/jsx-no-useless-fragment`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/react-jsx-no-useless-fragment.tsx): reject JSX fragments that wrap exactly one element child or have no meaningful content. The child (or nothing) can be returned directly.
479
473
  - [`react/no-array-index-key`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/react-no-array-index-key.tsx): rejects array map index parameters as JSX keys.
480
474
  - [`react/no-children-prop`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/react-no-children-prop.tsx): rejects passing children through a JSX `children` prop.
481
475
  - [`react/no-danger`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/react-no-danger.tsx): rejects `dangerouslySetInnerHTML`.
@@ -496,7 +490,7 @@ Source: [`eslint-plugin-react`](https://github.com/jsx-eslint/eslint-plugin-reac
496
490
 
497
491
  ### React performance
498
492
 
499
- Detects freshly-allocated reference values (arrays, objects, functions, JSX elements) passed as JSX props. A new reference invalidates `React.memo` / `useMemo` shallow checks on every render. Useful for performance-critical render paths; usually unnecessary for top-level pages. Diagnostics only fire on `.tsx` source files JSX heuristics rely on the file extension, so `.ts` files are skipped even when they contain JSX-like syntax.
493
+ Detects freshly-allocated reference values (arrays, objects, functions, JSX elements) passed as JSX props. A new reference invalidates `React.memo` / `useMemo` shallow checks on every render. Useful for performance-critical render paths; usually unnecessary for top-level pages. Diagnostics only fire on `.tsx` source files, JSX heuristics rely on the file extension, so `.ts` files are skipped even when they contain JSX-like syntax.
500
494
 
501
495
  Source: [`eslint-plugin-react-perf`](https://github.com/cvazac/eslint-plugin-react-perf).
502
496
 
@@ -507,7 +501,7 @@ Source: [`eslint-plugin-react-perf`](https://github.com/cvazac/eslint-plugin-rea
507
501
 
508
502
  ### JSX accessibility
509
503
 
510
- JSX accessibility rules applied to TSX (and JSX-in-TS) sources. Checks the static structure of JSX elements against WAI-ARIA authoring guidance interactive controls should be focusable, labels should reference a control, ARIA properties should match the element role, and so on. Runtime accessibility issues require live audits; this family catches the statically-decidable subset. Component alias settings, router-specific anchor settings, and autofixes are deferred.
504
+ JSX accessibility rules applied to TSX (and JSX-in-TS) sources. Checks the static structure of JSX elements against WAI-ARIA authoring guidance, interactive controls should be focusable, labels should reference a control, ARIA properties should match the element role, and so on. Runtime accessibility issues require live audits; this family catches the statically-decidable subset. Component alias settings, router-specific anchor settings, and autofixes are deferred.
511
505
 
512
506
  Source: [`eslint-plugin-jsx-a11y`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y).
513
507
 
@@ -526,7 +520,7 @@ Source: [`eslint-plugin-jsx-a11y`](https://github.com/jsx-eslint/eslint-plugin-j
526
520
  - [`jsx-a11y/heading-has-content`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/jsx-a11y-heading-has-content.tsx): rejects empty JSX headings.
527
521
  - [`jsx-a11y/html-has-lang`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/jsx-a11y-html-has-lang.tsx): requires `<html>` JSX elements to declare a non-empty `lang` attribute.
528
522
  - [`jsx-a11y/iframe-has-title`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/jsx-a11y-iframe-has-title.tsx): requires every `<iframe>` JSX element to declare a non-empty, unique `title`.
529
- - [`jsx-a11y/img-redundant-alt`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/jsx-a11y-img-redundant-alt.tsx): rejects redundant words such as *image*, *photo*, or *picture* inside the `alt` attribute of an `<img>`.
523
+ - [`jsx-a11y/img-redundant-alt`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/jsx-a11y-img-redundant-alt.tsx): rejects redundant words such as _image_, _photo_, or _picture_ inside the `alt` attribute of an `<img>`.
530
524
  - [`jsx-a11y/interactive-supports-focus`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/jsx-a11y-interactive-supports-focus.tsx): requires elements with interactive ARIA roles to be focusable.
531
525
  - [`jsx-a11y/label-has-associated-control`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/jsx-a11y-label-has-associated-control.tsx): requires `<label>` elements to wrap a form control or reference one via `htmlFor`.
532
526
  - [`jsx-a11y/label-has-for`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/jsx-a11y-label-has-for.tsx): deprecated predecessor of `label-has-associated-control` that checks the same nesting / `htmlFor` association requirement.
@@ -551,7 +545,7 @@ Source: [`eslint-plugin-jsx-a11y`](https://github.com/jsx-eslint/eslint-plugin-j
551
545
 
552
546
  ### Next.js
553
547
 
554
- Next.js framework rules applied to TypeScript and TSX sources inside Next.js apps. Cover static TS/TSX Next.js source patterns the framework's runtime treats as load-bearing pages/app routing, `<Head>` placement, font and script loading, image and link components, and common data export typos. Rules that need non-TypeScript files or runtime filesystem route discovery are intentionally conservative.
548
+ Next.js framework rules applied to TypeScript and TSX sources inside Next.js apps. Cover static TS/TSX Next.js source patterns the framework's runtime treats as load-bearing, pages/app routing, `<Head>` placement, font and script loading, image and link components, and common data export typos. Rules that need non-TypeScript files or runtime filesystem route discovery are intentionally conservative.
555
549
 
556
550
  Source: [`@next/eslint-plugin-next`](https://github.com/vercel/next.js/tree/canary/packages/eslint-plugin-next).
557
551
 
@@ -603,11 +597,11 @@ Source: [`eslint-plugin-solid`](https://github.com/solidjs-community/eslint-plug
603
597
  - [`solid/reactivity`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/solid-reactivity.tsx): flag bare signal accessors that break fine-grained reactivity tracking.
604
598
  - [`solid/self-closing-comp`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/solid-self-closing-comp.tsx): require empty JSX components to use the self-closing form.
605
599
  - [`solid/style-prop`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/solid-style-prop.tsx): reject camelCased CSS keys in JSX `style` object literals.
606
- - [`solid/validate-jsx-nesting`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/solid-validate-jsx-nesting.tsx): reject JSX nestings that the HTML parser would silently restructure at runtime `<p>` cannot contain block-level children, `<a>` cannot contain another `<a>`, and `<button>` cannot contain other interactive elements.
600
+ - [`solid/validate-jsx-nesting`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/solid-validate-jsx-nesting.tsx): reject JSX nestings that the HTML parser would silently restructure at runtime, `<p>` cannot contain block-level children, `<a>` cannot contain another `<a>`, and `<button>` cannot contain other interactive elements.
607
601
 
608
602
  ### Jest
609
603
 
610
- Jest test source rules. Apply to TypeScript test files that use the Jest runner (`describe`, `test`/`it`, `expect`, lifecycle hooks). Guard test-quality patterns the type system cannot detect unended assertions, focused tests left behind, duplicate hook calls.
604
+ Jest test source rules. Apply to TypeScript test files that use the Jest runner (`describe`, `test`/`it`, `expect`, lifecycle hooks). Guard test-quality patterns the type system cannot detect, unended assertions, focused tests left behind, duplicate hook calls.
611
605
 
612
606
  Source: [`eslint-plugin-jest`](https://github.com/jest-community/eslint-plugin-jest).
613
607
 
@@ -633,7 +627,7 @@ Source: [`eslint-plugin-jest`](https://github.com/jest-community/eslint-plugin-j
633
627
 
634
628
  ### Vitest
635
629
 
636
- Vitest test source rules. Vitest reuses much of Jest's testing surface but ships its own runner and configuration. These rules mirror the ergonomic subset of `eslint-plugin-jest` adapted for Vitest semantics focused or disabled tests, duplicate titles, missing or conditional assertions, standalone `expect` calls, done callbacks, invalid `expect` chains, invalid titles, returned test values, and `.length` assertions that should use `toHaveLength`.
630
+ Vitest test source rules. Vitest reuses much of Jest's testing surface but ships its own runner and configuration. These rules mirror the ergonomic subset of `eslint-plugin-jest` adapted for Vitest semantics, focused or disabled tests, duplicate titles, missing or conditional assertions, standalone `expect` calls, done callbacks, invalid `expect` chains, invalid titles, returned test values, and `.length` assertions that should use `toHaveLength`.
637
631
 
638
632
  Source: [`@vitest/eslint-plugin`](https://github.com/vitest-dev/eslint-plugin-vitest).
639
633
 
@@ -689,7 +683,7 @@ Source: [`eslint-plugin-testing-library`](https://github.com/testing-library/esl
689
683
 
690
684
  ### Playwright
691
685
 
692
- Playwright end-to-end test rules applied to TypeScript test files driven by the `@playwright/test` runner. Guard Playwright-specific patterns locator usage, web-first assertions, focused/slowed tests that would otherwise compile and run silently.
686
+ Playwright end-to-end test rules applied to TypeScript test files driven by the `@playwright/test` runner. Guard Playwright-specific patterns, locator usage, web-first assertions, focused/slowed tests. That would otherwise compile and run silently.
693
687
 
694
688
  Source: [`eslint-plugin-playwright`](https://github.com/playwright-community/eslint-plugin-playwright).
695
689
 
@@ -785,7 +779,7 @@ Source: [`@tanstack/eslint-plugin-query`](https://github.com/TanStack/query/tree
785
779
 
786
780
  ### Promise
787
781
 
788
- Promise correctness and style rules. Check the chain shape of Promise-using code: every chain ends with `catch`, no callback inside a `then`, no nested `.then().then()`, and so on. AST-local only type-aware Promise checks belong with `typescript/*` checker rules.
782
+ Promise correctness and style rules. Check the chain shape of Promise-using code: every chain ends with `catch`, no callback inside a `then`, no nested `.then().then()`, and so on. AST-local only, type-aware Promise checks belong with `typescript/*` checker rules.
789
783
 
790
784
  Source: [`eslint-plugin-promise`](https://github.com/eslint-community/eslint-plugin-promise).
791
785
 
@@ -831,7 +825,7 @@ Source: [`eslint-plugin-unicorn`](https://github.com/sindresorhus/eslint-plugin-
831
825
  - [`unicorn/filename-case`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-filename-case.ts): enforce a single case style (kebab/camel/snake/pascal) for source filenames.
832
826
  - [`unicorn/import-style`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-import-style.ts): restrict each module's allowed import styles (named only, default only, namespace only).
833
827
  - [`unicorn/isolated-functions`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-isolated-functions.ts): reject references to outer-scope variables inside functions marked as isolated (e.g., the body of a web worker).
834
- - [`unicorn/new-for-builtins`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-new-for-builtins.ts): require `new` when calling builtin constructors like `Error`, `Map`, `Set`, `Date` and forbid `new` on primitive wrappers like `String`, `Number`, `Boolean`.
828
+ - [`unicorn/new-for-builtins`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-new-for-builtins.ts): require `new` when calling builtin constructors like `Error`, `Map`, `Set`, `Date`, and forbid `new` on primitive wrappers like `String`, `Number`, `Boolean`.
835
829
  - [`unicorn/no-abusive-eslint-disable`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-abusive-eslint-disable.ts): require every `eslint-disable*` directive to name the rules it disables.
836
830
  - [`unicorn/no-accessor-recursion`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-accessor-recursion.ts): reject recursive reads on `this.<prop>` inside the getter / setter for `<prop>`.
837
831
  - [`unicorn/no-anonymous-default-export`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-anonymous-default-export.ts): require a name on every default-exported function, class, or object.
@@ -842,14 +836,14 @@ Source: [`eslint-plugin-unicorn`](https://github.com/sindresorhus/eslint-plugin-
842
836
  - [`unicorn/no-array-reverse`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-array-reverse.ts): prefer `Array#toReversed` over the mutating `Array#reverse`.
843
837
  - [`unicorn/no-array-sort`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-array-sort.ts): prefer `Array#toSorted` over the mutating `Array#sort`.
844
838
  - [`unicorn/no-await-expression-member`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-await-expression-member.ts): reject member access on an `await` expression without parens; require `(await x).y`.
845
- - [`unicorn/no-await-in-promise-methods`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-await-in-promise-methods.ts): reject `await` inside arrays passed to `Promise.all`/`Promise.allSettled`/`Promise.race`/`Promise.any` the awaits serialize the calls.
846
- - [`unicorn/no-console-spaces`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-console-spaces.ts): reject leading or trailing spaces in arguments to `console.log` and friends `console` already inserts spaces between arguments.
839
+ - [`unicorn/no-await-in-promise-methods`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-await-in-promise-methods.ts): reject `await` inside arrays passed to `Promise.all`/`Promise.allSettled`/`Promise.race`/`Promise.any`. The awaits serialize the calls.
840
+ - [`unicorn/no-console-spaces`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-console-spaces.ts): reject leading or trailing spaces in arguments to `console.log` and friends, `console` already inserts spaces between arguments.
847
841
  - [`unicorn/no-document-cookie`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-document-cookie.ts): reject direct reads or assignments to `document.cookie`; use the Cookie Store API or a wrapper.
848
842
  - [`unicorn/no-empty-file`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-empty-file.ts): reject source files whose only content is whitespace and/or comments.
849
843
  - [`unicorn/no-for-loop`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-for-loop.ts): prefer `for...of` over index-based `for` loops over arrays.
850
844
  - [`unicorn/no-hex-escape`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-hex-escape.ts): prefer Unicode escape (`©`) over hexadecimal escape (`\xA9`).
851
845
  - [`unicorn/no-immediate-mutation`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-immediate-mutation.ts): reject mutating a value on the same expression that produces it (`[...x].push(y)`); separate the construction and the mutation.
852
- - [`unicorn/no-instanceof-builtins`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-instanceof-builtins.ts): reject `instanceof Array`, `instanceof Error`, `instanceof Map`, etc. they fail across realms and for subclasses.
846
+ - [`unicorn/no-instanceof-builtins`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-instanceof-builtins.ts): reject `instanceof Array`, `instanceof Error`, `instanceof Map`, etc.. They fail across realms and for subclasses.
853
847
  - [`unicorn/no-invalid-fetch-options`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-invalid-fetch-options.ts): reject GET / HEAD `fetch()` calls that also set a request `body`, which throws at runtime.
854
848
  - [`unicorn/no-invalid-remove-event-listener`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-invalid-remove-event-listener.ts): reject `removeEventListener` calls whose handler argument is a fresh function reference and therefore matches no registered listener.
855
849
  - [`unicorn/no-keyword-prefix`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-keyword-prefix.ts): reject identifiers that start with a reserved word (`newFoo`, `classBar`).
@@ -866,7 +860,7 @@ Source: [`eslint-plugin-unicorn`](https://github.com/sindresorhus/eslint-plugin-
866
860
  - [`unicorn/no-process-exit`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-process-exit.ts): reject `process.exit()`; throw or return a non-zero status instead.
867
861
  - [`unicorn/no-single-promise-in-promise-methods`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-single-promise-in-promise-methods.ts): reject `Promise.all`/`Promise.race`/etc. called with a single-element array; the wrapper is redundant.
868
862
  - [`unicorn/no-static-only-class`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-static-only-class.ts): reject classes whose every member is `static`; use a plain module-level namespace instead.
869
- - [`unicorn/no-thenable`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-thenable.ts): reject defining a property named `then` on objects, modules, or classes `await` and Promise resolution accidentally invoke it.
863
+ - [`unicorn/no-thenable`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-thenable.ts): reject defining a property named `then` on objects, modules, or classes, `await` and Promise resolution accidentally invoke it.
870
864
  - [`unicorn/no-this-assignment`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-this-assignment.ts): reject `const self = this` and similar aliases; capture via arrow functions instead.
871
865
  - [`unicorn/no-typeof-undefined`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-typeof-undefined.ts): reject `typeof x === "undefined"`; compare against `undefined` directly.
872
866
  - [`unicorn/no-unnecessary-array-flat-depth`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-unnecessary-array-flat-depth.ts): reject `1` as the explicit depth argument of `Array#flat`; the default is already `1`.
@@ -882,7 +876,7 @@ Source: [`eslint-plugin-unicorn`](https://github.com/sindresorhus/eslint-plugin-
882
876
  - [`unicorn/no-useless-fallback-in-spread`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-useless-fallback-in-spread.ts): reject `...(x ?? {})` and similar fallbacks when spreading; the spread of `null`/`undefined` is already a no-op.
883
877
  - [`unicorn/no-useless-iterator-to-array`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-useless-iterator-to-array.ts): reject `[...iterator]` / `Array.from(iterator)` when the iterator can be consumed directly (e.g., inside `for...of`).
884
878
  - [`unicorn/no-useless-length-check`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-useless-length-check.ts): reject `arr.length` checks that the iteration method itself already handles.
885
- - [`unicorn/no-useless-promise-resolve-reject`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-useless-promise-resolve-reject.ts): reject `return Promise.resolve(x)` / `return Promise.reject(e)` inside `async` functions `return x` and `throw e` work identically.
879
+ - [`unicorn/no-useless-promise-resolve-reject`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-useless-promise-resolve-reject.ts): reject `return Promise.resolve(x)` / `return Promise.reject(e)` inside `async` functions, `return x` and `throw e` work identically.
886
880
  - [`unicorn/no-useless-spread`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-useless-spread.ts): reject spreading a single iterable into a new collection of the same kind (`[...arr]`, `{...obj}`) when the original would suffice.
887
881
  - [`unicorn/no-useless-switch-case`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-useless-switch-case.ts): reject `case` clauses with an empty body that immediately precede a `default` whose body executes for them.
888
882
  - [`unicorn/no-useless-undefined`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-no-useless-undefined.ts): reject explicit `undefined` returns, default initializers, and arguments where the omission has the same meaning.
@@ -957,12 +951,12 @@ Source: [`eslint-plugin-unicorn`](https://github.com/sindresorhus/eslint-plugin-
957
951
  - [`unicorn/switch-case-braces`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-switch-case-braces.ts): enforce a consistent presence/absence of `{}` braces around `case` clauses inside `switch`.
958
952
  - [`unicorn/switch-case-break-position`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-switch-case-break-position.ts): enforce a consistent position for `break` (or `return` / `throw`) inside `case` clauses.
959
953
  - [`unicorn/template-indent`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-template-indent.ts): re-indent the body of tagged template literals (`html`, `gql`, `sql`) to the indentation of the opening backtick.
960
- - [`unicorn/text-encoding-identifier-case`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-text-encoding-identifier-case.ts): enforce a canonical case for text-encoding identifiers `"utf-8"` (not `"UTF-8"` / `"utf8"`).
954
+ - [`unicorn/text-encoding-identifier-case`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-text-encoding-identifier-case.ts): enforce a canonical case for text-encoding identifiers, `"utf-8"` (not `"UTF-8"` / `"utf8"`).
961
955
  - [`unicorn/throw-new-error`](https://github.com/samchon/ttsc/blob/master/tests/test-lint/src/cases/unicorn-throw-new-error.ts): require `throw new Error(...)` over `throw Error(...)`.
962
956
 
963
957
  ### Regular expressions
964
958
 
965
- Regex-shape rules. Check the structure of regex literals emptiness, uselessness, flag ordering, shorthand classes, Unicode support. Some rules supersede the regex-related rules in [ESLint core](#eslint-core); both ids exist so projects can keep the legacy ESLint names alongside the regexp-plugin variants.
959
+ Regex-shape rules. Check the structure of regex literals, emptiness, uselessness, flag ordering, shorthand classes, Unicode support. Some rules supersede the regex-related rules in [ESLint core](#eslint-core); both ids exist so projects can keep the legacy ESLint names alongside the regexp-plugin variants.
966
960
 
967
961
  Source: [`eslint-plugin-regexp`](https://github.com/ota-meshi/eslint-plugin-regexp).
968
962
 
@@ -991,7 +985,7 @@ Source: [`eslint-plugin-regexp`](https://github.com/ota-meshi/eslint-plugin-rege
991
985
 
992
986
  ### Security
993
987
 
994
- Security-focused TypeScript source rules. Report likely security smells non-literal sinks for eval, file I/O, regex construction, child-process spawning, cryptographic primitives that warrant human review even if no exploit is statically provable. Treat findings as *hints*, not proofs.
988
+ Security-focused TypeScript source rules. Report likely security smells, non-literal sinks for eval, file I/O, regex construction, child-process spawning, cryptographic primitives. That warrant human review even if no exploit is statically provable. Treat findings as _hints_, not proofs.
995
989
 
996
990
  Source: [`eslint-plugin-security@4.0.0`](https://github.com/eslint-community/eslint-plugin-security).
997
991
 
@@ -1012,7 +1006,7 @@ Source: [`eslint-plugin-security@4.0.0`](https://github.com/eslint-community/esl
1012
1006
 
1013
1007
  ### JSDoc
1014
1008
 
1015
- Documentation-comment validation rules. Bundles `eslint-plugin-jsdoc` content checks (tag names, parameter coverage, descriptions) with the lone `eslint-plugin-tsdoc` syntax check (`jsdoc/tsdoc-syntax`) both target `/** ... */` comments. Formatting concerns (alignment, indentation) are configured through the top-level [`format`](#format) block, not here.
1009
+ Documentation-comment validation rules. Bundles `eslint-plugin-jsdoc` content checks (tag names, parameter coverage, descriptions) with the lone `eslint-plugin-tsdoc` syntax check (`jsdoc/tsdoc-syntax`). Both target `/** ... */` comments. Formatting concerns (alignment, indentation) are configured through the top-level [`format`](#format) block, not here.
1016
1010
 
1017
1011
  Source: [`eslint-plugin-jsdoc`](https://github.com/gajus/eslint-plugin-jsdoc), [`eslint-plugin-tsdoc`](https://github.com/microsoft/tsdoc).
1018
1012
 
@@ -1032,7 +1026,7 @@ Source: [`eslint-plugin-jsdoc`](https://github.com/gajus/eslint-plugin-jsdoc), [
1032
1026
 
1033
1027
  ### Functional
1034
1028
 
1035
- Functional-programming policy rules. Push code toward immutability, side-effect-free expressions, and expression-style control flow. Most rules are useful in pieces projects rarely enable the whole family at `"error"`. Enabling the whole set together expresses a strict functional-core / imperative-shell discipline. Diagnostic-only: `ttsc fix` does not rewrite mutation, classes, exceptions, loops, or branching into a functional design.
1029
+ Functional-programming policy rules. Push code toward immutability, side-effect-free expressions, and expression-style control flow. Most rules are useful in pieces, projects rarely enable the whole family at `"error"`. Enabling the whole set together expresses a strict functional-core / imperative-shell discipline. Diagnostic-only: `ttsc fix` does not rewrite mutation, classes, exceptions, loops, or branching into a functional design.
1036
1030
 
1037
1031
  Source: [`eslint-plugin-functional`](https://github.com/eslint-functional/eslint-plugin-functional).
1038
1032
 
@@ -1080,7 +1074,7 @@ export default {
1080
1074
 
1081
1075
  ### Architecture boundaries
1082
1076
 
1083
- Architecture-boundary rules enforce import direction and module visibility between configured source-path *elements* (layers, features, apps in a monorepo). Every rule operates on the *resolved source file* of an import relative imports are followed to the real `.ts`/`.tsx`/`.d.ts` file before classification. Boundary diagnostics do not offer autofixes a violation usually needs an API or architecture decision, not a mechanical import rewrite.
1077
+ Architecture-boundary rules enforce import direction and module visibility between configured source-path _elements_ (layers, features, apps in a monorepo). Every rule operates on the _resolved source file_ of an import, relative imports are followed to the real `.ts`/`.tsx`/`.d.ts` file before classification. Boundary diagnostics do not offer autofixes, a violation usually needs an API or architecture decision, not a mechanical import rewrite.
1084
1078
 
1085
1079
  Source: ported from [`eslint-plugin-boundaries`](https://github.com/javierbrea/eslint-plugin-boundaries).
1086
1080
 
@@ -1138,7 +1132,7 @@ export default {
1138
1132
 
1139
1133
  `ttsc` copies each declared contributor's Go source into a sub-package of `@ttsc/lint`'s module at build time, so the resulting binary has both built-in and contributor rules registered before `main`. Authoring instructions and the public Go API live in the [`@ttsc/lint` walkthrough → How a contributor package ships](https://ttsc.dev/docs/development/walkthroughs/lint#how-a-contributor-package-ships).
1140
1134
 
1141
- Contributor rules emit autofixes the same way built-ins do call `ctx.ReportFix(node, message, edits...)` or `ctx.ReportRangeFix(pos, end, message, edits...)`. The `rule/astutil` package re-exports the byte-range helpers built-ins use (`NodeText`, `KeywordStart`, `FindKeyword`, `TokenRange`). See the [contributor autofix path](https://ttsc.dev/docs/development/walkthroughs/lint#the-contributor-autofix-path) section for the full contract and an example.
1135
+ Contributor rules emit autofixes the same way built-ins do, call `ctx.ReportFix(node, message, edits...)` or `ctx.ReportRangeFix(pos, end, message, edits...)`. The `rule/astutil` package re-exports the byte-range helpers built-ins use (`NodeText`, `KeywordStart`, `FindKeyword`, `TokenRange`). See the [contributor autofix path](https://ttsc.dev/docs/development/walkthroughs/lint#the-contributor-autofix-path) section for the full contract and an example.
1142
1136
 
1143
1137
  ## Sponsors
1144
1138
 
@@ -1151,7 +1145,7 @@ Your [donation](https://github.com/sponsors/samchon) encourages `ttsc` developme
1151
1145
  ## References
1152
1146
 
1153
1147
  <!--
1154
- AGENT INSTRUCTIONS adding a new upstream reference.
1148
+ AGENT INSTRUCTIONS, adding a new upstream reference.
1155
1149
 
1156
1150
  When you add a new rule family to [Rules](#rules), do all of:
1157
1151
 
@@ -1164,7 +1158,7 @@ When you add a new rule family to [Rules](#rules), do all of:
1164
1158
  that single upstream, mention the namespace in `### Claim ownership` so the
1165
1159
  maintainers know the port belongs to their family. The paragraph already lists
1166
1160
  `react/*, jest/*, playwright/*, tanstack-query/*, promise/*, and the other family
1167
- namespaces` extend that list naturally; do not start a new sentence per family.
1161
+ namespaces`, extend that list naturally; do not start a new sentence per family.
1168
1162
  3. Do NOT put license parentheticals (`(MIT)`, `(BSD-3-Clause)`, etc.) after the
1169
1163
  link. Reader clicks through if they need the license.
1170
1164
  4. Order is roughly the same as the family ordering in [Rules](#rules); insert at
@@ -1199,9 +1193,8 @@ When you add a new rule family to [Rules](#rules), do all of:
1199
1193
 
1200
1194
  ### Claim ownership
1201
1195
 
1202
- To the maintainers of every plugin listed above: the rule semantics under `react/*`, `jest/*`, `playwright/*`, `tanstack-query/*`, `promise/*`, and the other family namespaces inside `@ttsc/lint` are a Go re-implementation of your work for the TypeScript-Go Checker. The intent is convenience projects on `ttsc` get your rules without standing up a separate ESLint process not ownership.
1196
+ To the maintainers of every plugin listed above: the rule semantics under `react/*`, `jest/*`, `playwright/*`, `tanstack-query/*`, `promise/*`, and the other family namespaces inside `@ttsc/lint` are a Go re-implementation of your work for the TypeScript-Go Checker. The intent is convenience, projects on `ttsc` get your rules without standing up a separate ESLint process, not ownership.
1203
1197
 
1204
- If you would prefer to publish a first-party `@ttsc/lint` plugin for your family yourself, you are welcome to take the Go sources under [`packages/lint/linthost/rules_*.go`](https://github.com/samchon/ttsc/tree/master/packages/lint/linthost) and the fixtures under [`tests/test-lint/src/cases/`](https://github.com/samchon/ttsc/tree/master/tests/test-lint/src/cases) and ship them as your own contributor plugin. Open an issue at [samchon/ttsc](https://github.com/samchon/ttsc/issues) when the upstream package is ready, and I will retire the in-tree port and add a redirect line under [Rules](#rules) pointing at your package. Same offer for partial coverage name a subset and I will remove just those rules.
1198
+ If you would prefer to publish a first-party `@ttsc/lint` plugin for your family yourself, you are welcome to take the Go sources under [`packages/lint/linthost/rules_*.go`](https://github.com/samchon/ttsc/tree/master/packages/lint/linthost) and the fixtures under [`tests/test-lint/src/cases/`](https://github.com/samchon/ttsc/tree/master/tests/test-lint/src/cases) and ship them as your own contributor plugin. Open an issue at [samchon/ttsc](https://github.com/samchon/ttsc/issues) when the upstream package is ready, and I will retire the in-tree port and add a redirect line under [Rules](#rules) pointing at your package. Same offer for partial coverage. Name a subset and I will remove just those rules.
1205
1199
 
1206
1200
  The contributor-plugin walkthrough is the [`@ttsc/lint` development guide](https://ttsc.dev/docs/development/walkthroughs/lint).
1207
-
package/linthost/lsp.go CHANGED
@@ -5,6 +5,7 @@ import (
5
5
  "errors"
6
6
  "flag"
7
7
  "fmt"
8
+ "io"
8
9
  "io/fs"
9
10
  "net/url"
10
11
  "os"
@@ -12,6 +13,10 @@ import (
12
13
  "strings"
13
14
  "unicode/utf16"
14
15
  "unicode/utf8"
16
+
17
+ shimast "github.com/microsoft/typescript-go/shim/ast"
18
+ shimcore "github.com/microsoft/typescript-go/shim/core"
19
+ shimparser "github.com/microsoft/typescript-go/shim/parser"
15
20
  )
16
21
 
17
22
  const (
@@ -67,8 +72,13 @@ type lspCommandOptions struct {
67
72
  argumentsJSON string
68
73
  command string
69
74
  contextJSON string
70
- cwd string
71
- pluginsJSON string
75
+ // contentStdin reports whether the caller passed --content-stdin. When
76
+ // set, RunLSPExecuteCommand reads the FULL document buffer from os.Stdin
77
+ // (to EOF) and formats that text in memory instead of reading the target
78
+ // file from disk. See lspFormatBuffer.
79
+ contentStdin bool
80
+ cwd string
81
+ pluginsJSON string
72
82
  // rangeJSON is accepted from the ttsc LSP server
73
83
  // (`internal/lspserver/lsp_native_plugin_source.go`) for forward
74
84
  // compatibility, but no current code path consumes it — code actions
@@ -180,6 +190,24 @@ func RunLSPExecuteCommand(args []string) int {
180
190
  return 2
181
191
  }
182
192
  opts.uri = uri
193
+ // --content-stdin selects the lightweight in-memory format path: the full
194
+ // document buffer is read from stdin and formatted with AST+source rules
195
+ // only, with no temp-workspace copy and no tsgo Program. It applies to
196
+ // ttsc.format.document; ttsc.lint.fixAll under --content-stdin is out of
197
+ // scope (lint-class fixes can require a type checker), so it falls back to
198
+ // the disk-based path below.
199
+ if opts.contentStdin && opts.command == commandFormatDocument {
200
+ content, err := io.ReadAll(os.Stdin)
201
+ if err != nil {
202
+ fmt.Fprintf(os.Stderr, "@ttsc/lint lsp-execute-command: read --content-stdin: %v\n", err)
203
+ return 2
204
+ }
205
+ edit, code := lspFormatBuffer(string(content), opts)
206
+ if code != 0 {
207
+ return code
208
+ }
209
+ return writeJSON(edit)
210
+ }
183
211
  edit, code := lspWorkspaceEditForCommand(opts)
184
212
  if code != 0 {
185
213
  return code
@@ -198,6 +226,7 @@ func parseLSPCommandOptions(name string, args []string) (*lspCommandOptions, boo
198
226
  contextJSON := fs.String("context-json", "", "")
199
227
  command := fs.String("command", "", "")
200
228
  argumentsJSON := fs.String("arguments-json", "", "")
229
+ contentStdin := fs.Bool("content-stdin", false, "")
201
230
  if err := fs.Parse(args); err != nil {
202
231
  return nil, false
203
232
  }
@@ -210,6 +239,7 @@ func parseLSPCommandOptions(name string, args []string) (*lspCommandOptions, boo
210
239
  argumentsJSON: *argumentsJSON,
211
240
  command: *command,
212
241
  contextJSON: *contextJSON,
242
+ contentStdin: *contentStdin,
213
243
  cwd: resolvedCwd,
214
244
  pluginsJSON: *pluginsJSON,
215
245
  rangeJSON: *rangeJSON,
@@ -421,6 +451,123 @@ func lspWorkspaceEditForCommand(opts *lspCommandOptions) (*lspWorkspaceEdit, int
421
451
  return workspaceEditForFullDocument(opts.uri, string(original), string(next)), 0
422
452
  }
423
453
 
454
+ // lspFormatBuffer formats an in-memory document buffer using only the
455
+ // format-class rules, with no tsgo Program and no temp-workspace copy. It is
456
+ // the lightweight path behind --content-stdin for ttsc.format.document.
457
+ //
458
+ // Format rules are AST+source only (`IsFormat() == true`); none implement
459
+ // typeAwareRule, so the engine runs them with a nil checker. The document
460
+ // content comes entirely from `content` — the file on disk at opts.uri is
461
+ // never read — so an editor can format an unsaved buffer without paying the
462
+ // disk-copy + full-program-load cost of lspWorkspaceEditForCommand.
463
+ //
464
+ // Returns the same WorkspaceEdit shape as the disk path, or (nil, 0) on a
465
+ // no-op (no fixable findings, or text unchanged after convergence).
466
+ func lspFormatBuffer(content string, opts *lspCommandOptions) (*lspWorkspaceEdit, int) {
467
+ target, err := filePathFromURI(opts.uri)
468
+ if err != nil {
469
+ fmt.Fprintln(os.Stderr, err)
470
+ return nil, 2
471
+ }
472
+ // Guard rails mirror lspWorkspaceEditForCommand: skip targets outside the
473
+ // project root or inside node_modules.
474
+ if _, ok := projectRelativePath(opts.cwd, target); !ok {
475
+ fmt.Fprintf(os.Stderr, "@ttsc/lint: LSP command target %s is outside cwd %s\n", target, opts.cwd)
476
+ return nil, 2
477
+ }
478
+ if projectPathHasSegment(opts.cwd, target, "node_modules") {
479
+ return nil, 0
480
+ }
481
+
482
+ rules, err := loadRules(opts.pluginsJSON, opts.cwd, opts.tsconfig)
483
+ if err != nil {
484
+ fmt.Fprintln(os.Stderr, err)
485
+ return nil, 2
486
+ }
487
+ rules = formatCommandResolver{inner: rules}
488
+ engine := NewEngineWithResolver(rules)
489
+ if engine.NeedsTypeChecker() {
490
+ // A format-class contributor rule (formatContributorAdapter) needs the type
491
+ // checker, which the single-file in-memory parse can't supply. Fall back to
492
+ // the disk path, which builds a full program with a checker, so the result
493
+ // matches `ttsc format`; the dirty buffer can't be honored for these rules.
494
+ // Built-in format rules are AST-only, so they keep the fast in-memory path.
495
+ return lspWorkspaceEditForCommand(opts)
496
+ }
497
+ scriptKind := scriptKindForPath(target)
498
+
499
+ text := content
500
+ converged := false
501
+ for pass := 0; pass < maxFormatPasses; pass++ {
502
+ file := shimparser.ParseSourceFile(shimast.SourceFileParseOptions{FileName: target}, text, scriptKind)
503
+ if file == nil {
504
+ // Match the disk path: a buffer we can't parse is a benign no-op, not a
505
+ // hard error — don't fight the editor's own diagnostics on a dirty buffer.
506
+ return nil, 0
507
+ }
508
+ findings := filterFormatFindings(engine.Run([]*shimast.SourceFile{file}, nil))
509
+ next, applied := applyFindingFixesToText(text, findings)
510
+ if applied == 0 {
511
+ converged = true
512
+ break
513
+ }
514
+ text = next
515
+ }
516
+ if !converged {
517
+ fmt.Fprintf(os.Stderr,
518
+ "@ttsc/lint: LSP %s cascade did not converge after %d passes\n",
519
+ opts.command, maxFormatPasses)
520
+ return nil, 2
521
+ }
522
+ return workspaceEditForFullDocument(opts.uri, content, text), 0
523
+ }
524
+
525
+ // scriptKindForPath maps a file extension to the tsgo ScriptKind the parser
526
+ // needs so TS/JSX-only syntax is recognized. Mirrors the test helpers'
527
+ // ScriptKind selection (helpers_test.go parseTSFile/parseTSXFile).
528
+ func scriptKindForPath(path string) shimcore.ScriptKind {
529
+ switch strings.ToLower(filepath.Ext(path)) {
530
+ case ".tsx":
531
+ return shimcore.ScriptKindTSX
532
+ case ".jsx":
533
+ return shimcore.ScriptKindJSX
534
+ case ".js", ".cjs", ".mjs":
535
+ return shimcore.ScriptKindJS
536
+ default:
537
+ return shimcore.ScriptKindTS
538
+ }
539
+ }
540
+
541
+ // applyFindingFixesToText is the in-memory counterpart of
542
+ // applyFindingFixes/applyTextEditsToFile (fix.go): it collects every fixable
543
+ // finding's TextEdit, selects a non-overlapping set with the same
544
+ // selectTextEdits logic, applies them right-to-left to `text`, and returns the
545
+ // new string plus the number of edits applied. It never writes to disk and
546
+ // never reloads a Program. Findings carry byte offsets into the same `text`
547
+ // that was just parsed, so no per-file grouping is needed.
548
+ func applyFindingFixesToText(text string, findings []*Finding) (string, int) {
549
+ edits := make([]TextEdit, 0, len(findings))
550
+ for _, finding := range findings {
551
+ if finding == nil || len(finding.Fix) == 0 {
552
+ continue
553
+ }
554
+ edits = append(edits, finding.Fix...)
555
+ }
556
+ selected := selectTextEdits(len(text), edits)
557
+ if len(selected) == 0 {
558
+ return text, 0
559
+ }
560
+ next := text
561
+ for i := len(selected) - 1; i >= 0; i-- {
562
+ edit := selected[i]
563
+ next = next[:edit.Pos] + edit.Text + next[edit.End:]
564
+ }
565
+ if next == text {
566
+ return text, 0
567
+ }
568
+ return next, len(selected)
569
+ }
570
+
424
571
  func workspaceEditForFullDocument(uri string, original string, next string) *lspWorkspaceEdit {
425
572
  if original == next {
426
573
  return nil
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttsc/lint",
3
- "version": "0.14.0-dev.20260528.1",
3
+ "version": "0.14.0-dev.20260529.2",
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",
@@ -36,7 +36,7 @@
36
36
  "@typescript/native-preview": "7.0.0-dev.20260527.2",
37
37
  "@types/node": "^25.3.0",
38
38
  "rimraf": "^6.1.2",
39
- "ttsc": "0.14.0-dev.20260528.1"
39
+ "ttsc": "0.14.0-dev.20260529.2"
40
40
  },
41
41
  "repository": {
42
42
  "type": "git",