@ttsc/lint 0.13.1 → 0.14.0-dev.20260528

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 (464) hide show
  1. package/README.md +948 -69
  2. package/lib/defaultFormat.d.ts +9 -6
  3. package/lib/defaultFormat.js +9 -6
  4. package/lib/defaultFormat.js.map +1 -1
  5. package/lib/index.d.ts +46 -0
  6. package/lib/index.js +35 -10
  7. package/lib/index.js.map +1 -1
  8. package/lib/structures/ITtscLintConfig.d.ts +12 -6
  9. package/lib/structures/{ITtscLintFormatConfig.d.ts → ITtscLintFormat.d.ts} +2 -2
  10. package/lib/structures/{TtscLintRuleMap.js → ITtscLintFormat.js} +1 -1
  11. package/lib/structures/ITtscLintFormat.js.map +1 -0
  12. package/lib/structures/TtscLintRuleSetting.d.ts +49 -0
  13. package/lib/structures/{TtscLintRuleOptions.js → TtscLintRuleSetting.js} +1 -1
  14. package/lib/structures/TtscLintRuleSetting.js.map +1 -0
  15. package/lib/structures/index.d.ts +3 -4
  16. package/lib/structures/index.js +3 -4
  17. package/lib/structures/index.js.map +1 -1
  18. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.d.ts +104 -0
  19. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js +14 -0
  20. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js.map +1 -0
  21. package/lib/structures/rules/ITtscLintBoundariesRules.d.ts +79 -0
  22. package/lib/structures/rules/ITtscLintBoundariesRules.js +3 -0
  23. package/lib/structures/rules/ITtscLintBoundariesRules.js.map +1 -0
  24. package/lib/structures/rules/ITtscLintContributorRules.d.ts +17 -0
  25. package/lib/structures/rules/ITtscLintContributorRules.js +3 -0
  26. package/lib/structures/rules/ITtscLintContributorRules.js.map +1 -0
  27. package/lib/structures/rules/ITtscLintCoreRules.d.ts +1257 -0
  28. package/lib/structures/{ITtscLintFormatConfig.js → rules/ITtscLintCoreRules.js} +1 -1
  29. package/lib/structures/rules/ITtscLintCoreRules.js.map +1 -0
  30. package/lib/structures/rules/ITtscLintCypressRuleOptions.d.ts +17 -0
  31. package/lib/structures/rules/ITtscLintCypressRuleOptions.js +10 -0
  32. package/lib/structures/rules/ITtscLintCypressRuleOptions.js.map +1 -0
  33. package/lib/structures/rules/ITtscLintCypressRules.d.ts +129 -0
  34. package/lib/structures/rules/ITtscLintCypressRules.js +3 -0
  35. package/lib/structures/rules/ITtscLintCypressRules.js.map +1 -0
  36. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.d.ts +157 -0
  37. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js +13 -0
  38. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js.map +1 -0
  39. package/lib/structures/rules/ITtscLintFunctionalRules.d.ts +167 -0
  40. package/lib/structures/rules/ITtscLintFunctionalRules.js +3 -0
  41. package/lib/structures/rules/ITtscLintFunctionalRules.js.map +1 -0
  42. package/lib/structures/rules/ITtscLintJestRules.d.ts +201 -0
  43. package/lib/structures/rules/ITtscLintJestRules.js +3 -0
  44. package/lib/structures/rules/ITtscLintJestRules.js.map +1 -0
  45. package/lib/structures/rules/ITtscLintJsdocRules.d.ts +140 -0
  46. package/lib/structures/rules/ITtscLintJsdocRules.js +3 -0
  47. package/lib/structures/rules/ITtscLintJsdocRules.js.map +1 -0
  48. package/lib/structures/rules/ITtscLintJsxA11yRules.d.ts +302 -0
  49. package/lib/structures/rules/ITtscLintJsxA11yRules.js +3 -0
  50. package/lib/structures/rules/ITtscLintJsxA11yRules.js.map +1 -0
  51. package/lib/structures/rules/ITtscLintNextjsRules.d.ts +185 -0
  52. package/lib/structures/rules/ITtscLintNextjsRules.js +3 -0
  53. package/lib/structures/rules/ITtscLintNextjsRules.js.map +1 -0
  54. package/lib/structures/rules/ITtscLintPlaywrightRules.d.ts +330 -0
  55. package/lib/structures/rules/ITtscLintPlaywrightRules.js +3 -0
  56. package/lib/structures/rules/ITtscLintPlaywrightRules.js.map +1 -0
  57. package/lib/structures/rules/ITtscLintPromiseRules.d.ts +188 -0
  58. package/lib/structures/rules/ITtscLintPromiseRules.js +3 -0
  59. package/lib/structures/rules/ITtscLintPromiseRules.js.map +1 -0
  60. package/lib/structures/rules/ITtscLintReactPerfRuleOptions.d.ts +18 -0
  61. package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js +8 -0
  62. package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js.map +1 -0
  63. package/lib/structures/rules/ITtscLintReactPerfRules.d.ts +51 -0
  64. package/lib/structures/rules/ITtscLintReactPerfRules.js +3 -0
  65. package/lib/structures/rules/ITtscLintReactPerfRules.js.map +1 -0
  66. package/lib/structures/rules/ITtscLintReactRuleOptions.d.ts +39 -0
  67. package/lib/structures/rules/ITtscLintReactRuleOptions.js +12 -0
  68. package/lib/structures/rules/ITtscLintReactRuleOptions.js.map +1 -0
  69. package/lib/structures/rules/ITtscLintReactRules.d.ts +289 -0
  70. package/lib/structures/rules/ITtscLintReactRules.js +3 -0
  71. package/lib/structures/rules/ITtscLintReactRules.js.map +1 -0
  72. package/lib/structures/rules/ITtscLintRegexpRules.d.ts +190 -0
  73. package/lib/structures/rules/ITtscLintRegexpRules.js +3 -0
  74. package/lib/structures/rules/ITtscLintRegexpRules.js.map +1 -0
  75. package/lib/structures/rules/ITtscLintRuleOptionsMap.d.ts +66 -0
  76. package/lib/structures/rules/ITtscLintRuleOptionsMap.js +3 -0
  77. package/lib/structures/rules/ITtscLintRuleOptionsMap.js.map +1 -0
  78. package/lib/structures/rules/ITtscLintRules.d.ts +55 -0
  79. package/lib/structures/{TtscLintRule.js → rules/ITtscLintRules.js} +1 -1
  80. package/lib/structures/rules/ITtscLintRules.js.map +1 -0
  81. package/lib/structures/rules/ITtscLintSecurityRules.d.ts +148 -0
  82. package/lib/structures/rules/ITtscLintSecurityRules.js +3 -0
  83. package/lib/structures/rules/ITtscLintSecurityRules.js.map +1 -0
  84. package/lib/structures/rules/ITtscLintSolidRules.d.ts +181 -0
  85. package/lib/structures/rules/ITtscLintSolidRules.js +3 -0
  86. package/lib/structures/rules/ITtscLintSolidRules.js.map +1 -0
  87. package/lib/structures/rules/ITtscLintStorybookRuleOptions.d.ts +21 -0
  88. package/lib/structures/rules/ITtscLintStorybookRuleOptions.js +9 -0
  89. package/lib/structures/rules/ITtscLintStorybookRuleOptions.js.map +1 -0
  90. package/lib/structures/rules/ITtscLintStorybookRules.d.ts +174 -0
  91. package/lib/structures/rules/ITtscLintStorybookRules.js +3 -0
  92. package/lib/structures/rules/ITtscLintStorybookRules.js.map +1 -0
  93. package/lib/structures/rules/ITtscLintTanstackQueryRules.d.ts +94 -0
  94. package/lib/structures/rules/ITtscLintTanstackQueryRules.js +3 -0
  95. package/lib/structures/rules/ITtscLintTanstackQueryRules.js.map +1 -0
  96. package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.d.ts +22 -0
  97. package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js +10 -0
  98. package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js.map +1 -0
  99. package/lib/structures/rules/ITtscLintTestingLibraryRules.d.ts +310 -0
  100. package/lib/structures/rules/ITtscLintTestingLibraryRules.js +3 -0
  101. package/lib/structures/rules/ITtscLintTestingLibraryRules.js.map +1 -0
  102. package/lib/structures/rules/ITtscLintTypeScriptRules.d.ts +1132 -0
  103. package/lib/structures/rules/ITtscLintTypeScriptRules.js +3 -0
  104. package/lib/structures/rules/ITtscLintTypeScriptRules.js.map +1 -0
  105. package/lib/structures/rules/ITtscLintUnicornRules.d.ts +997 -0
  106. package/lib/structures/rules/ITtscLintUnicornRules.js +3 -0
  107. package/lib/structures/rules/ITtscLintUnicornRules.js.map +1 -0
  108. package/lib/structures/rules/ITtscLintVitestRules.d.ts +141 -0
  109. package/lib/structures/rules/ITtscLintVitestRules.js +3 -0
  110. package/lib/structures/rules/ITtscLintVitestRules.js.map +1 -0
  111. package/lib/structures/rules/index.d.ts +31 -0
  112. package/lib/structures/rules/index.js +48 -0
  113. package/lib/structures/rules/index.js.map +1 -0
  114. package/linthost/ast_helpers.go +30 -5
  115. package/linthost/config.go +48 -17
  116. package/linthost/config_format.go +9 -9
  117. package/linthost/directives.go +67 -25
  118. package/linthost/dispatch.go +14 -3
  119. package/linthost/engine.go +152 -31
  120. package/linthost/fix.go +2 -2
  121. package/linthost/lsp.go +747 -0
  122. package/linthost/print_dispatch.go +2 -2
  123. package/linthost/print_nodes_function.go +2 -2
  124. package/linthost/print_nodes_object.go +1 -1
  125. package/linthost/rule_names.go +14 -0
  126. package/linthost/rules_arrays.go +2 -2
  127. package/linthost/rules_boundaries.go +532 -0
  128. package/linthost/rules_camelcase.go +133 -0
  129. package/linthost/rules_complexity.go +94 -0
  130. package/linthost/rules_consistent_return.go +130 -0
  131. package/linthost/rules_console.go +1 -1
  132. package/linthost/rules_core_extra.go +739 -0
  133. package/linthost/rules_curly.go +70 -0
  134. package/linthost/rules_cypress.go +608 -0
  135. package/linthost/rules_debugger.go +2 -2
  136. package/linthost/rules_default_case.go +39 -0
  137. package/linthost/rules_default_case_last.go +46 -0
  138. package/linthost/rules_dupes.go +3 -3
  139. package/linthost/rules_empty.go +3 -3
  140. package/linthost/rules_escape.go +44 -24
  141. package/linthost/rules_eval.go +2 -2
  142. package/linthost/rules_finally.go +2 -2
  143. package/linthost/rules_format_jsdoc.go +1 -1
  144. package/linthost/rules_format_print_width.go +9 -9
  145. package/linthost/rules_format_quotes.go +1 -1
  146. package/linthost/rules_format_semi.go +1 -1
  147. package/linthost/rules_format_sort_imports.go +1 -1
  148. package/linthost/rules_format_trailing_comma.go +1 -1
  149. package/linthost/rules_functional.go +967 -0
  150. package/linthost/rules_gap.go +24 -45
  151. package/linthost/rules_grouped_accessor_pairs.go +87 -0
  152. package/linthost/rules_guard_for_in.go +198 -0
  153. package/linthost/rules_id_length.go +77 -0
  154. package/linthost/rules_imports.go +70 -2
  155. package/linthost/rules_init_declarations.go +53 -0
  156. package/linthost/rules_jest.go +618 -0
  157. package/linthost/rules_jsdoc.go +502 -0
  158. package/linthost/rules_jsx_a11y.go +1264 -0
  159. package/linthost/rules_logic.go +12 -12
  160. package/linthost/rules_loops.go +1 -1
  161. package/linthost/rules_max_classes_per_file.go +58 -0
  162. package/linthost/rules_max_depth.go +83 -0
  163. package/linthost/rules_max_lines.go +101 -0
  164. package/linthost/rules_max_lines_per_function.go +57 -0
  165. package/linthost/rules_max_nested_callbacks.go +61 -0
  166. package/linthost/rules_max_params.go +49 -0
  167. package/linthost/rules_max_statements.go +59 -0
  168. package/linthost/rules_misc.go +1 -1
  169. package/linthost/rules_nextjs.go +697 -0
  170. package/linthost/rules_no_else_return.go +75 -0
  171. package/linthost/rules_no_empty_named_blocks.go +91 -0
  172. package/linthost/rules_no_extend_native.go +51 -0
  173. package/linthost/rules_no_import_assign.go +140 -0
  174. package/linthost/rules_no_invalid_this.go +52 -0
  175. package/linthost/rules_no_loop_func.go +85 -0
  176. package/linthost/rules_no_magic_numbers.go +123 -0
  177. package/linthost/rules_no_mixed_operators.go +80 -0
  178. package/linthost/rules_no_param_reassign.go +98 -0
  179. package/linthost/rules_no_redeclare.go +270 -0
  180. package/linthost/rules_no_restricted_imports.go +105 -0
  181. package/linthost/rules_no_restricted_syntax.go +49 -0
  182. package/linthost/rules_no_shadow.go +147 -0
  183. package/linthost/rules_no_unreachable.go +77 -0
  184. package/linthost/rules_no_useless_assignment.go +120 -0
  185. package/linthost/rules_no_useless_constructor.go +245 -0
  186. package/linthost/rules_no_useless_return.go +51 -0
  187. package/linthost/rules_params.go +1 -1
  188. package/linthost/rules_playwright.go +788 -0
  189. package/linthost/rules_prefer_arrow_callback.go +124 -0
  190. package/linthost/rules_prefer_destructuring.go +98 -0
  191. package/linthost/rules_prefer_named_capture_group.go +129 -0
  192. package/linthost/rules_prefer_rest_params.go +94 -0
  193. package/linthost/rules_problems.go +41 -30
  194. package/linthost/rules_promise.go +1128 -73
  195. package/linthost/rules_protos.go +2 -2
  196. package/linthost/rules_react.go +773 -0
  197. package/linthost/rules_react_extras.go +227 -0
  198. package/linthost/rules_react_hooks.go +848 -0
  199. package/linthost/rules_react_perf.go +293 -0
  200. package/linthost/rules_react_refresh.go +583 -0
  201. package/linthost/rules_regexp.go +410 -0
  202. package/linthost/rules_security.go +830 -0
  203. package/linthost/rules_self.go +2 -2
  204. package/linthost/rules_solid.go +1073 -0
  205. package/linthost/rules_sort_imports.go +69 -0
  206. package/linthost/rules_sort_keys.go +134 -0
  207. package/linthost/rules_storybook.go +1176 -0
  208. package/linthost/rules_strings.go +4 -4
  209. package/linthost/rules_suggestions.go +38 -38
  210. package/linthost/rules_tanstack_query.go +844 -0
  211. package/linthost/rules_testing_library.go +1204 -0
  212. package/linthost/rules_throw.go +1 -1
  213. package/linthost/rules_ts.go +19 -19
  214. package/linthost/rules_ts_async.go +399 -0
  215. package/linthost/rules_ts_class_literal_property_style.go +115 -0
  216. package/linthost/rules_ts_consistent_type_exports.go +256 -0
  217. package/linthost/rules_ts_explicit_function_return_type.go +67 -0
  218. package/linthost/rules_ts_extra.go +155 -36
  219. package/linthost/rules_ts_no_base_to_string.go +218 -0
  220. package/linthost/rules_ts_no_confusing_void.go +72 -0
  221. package/linthost/rules_ts_no_deprecated.go +195 -0
  222. package/linthost/rules_ts_no_for_in_array.go +84 -0
  223. package/linthost/rules_ts_no_magic_numbers.go +124 -0
  224. package/linthost/rules_ts_no_meaningless_void_operator.go +84 -0
  225. package/linthost/rules_ts_no_misused_spread.go +104 -0
  226. package/linthost/rules_ts_no_redundant_type_constituents.go +113 -0
  227. package/linthost/rules_ts_no_restricted_types.go +62 -0
  228. package/linthost/rules_ts_no_unnecessary_boolean_literal_compare.go +129 -0
  229. package/linthost/rules_ts_no_unnecessary_condition.go +250 -0
  230. package/linthost/rules_ts_no_unnecessary_qualifier.go +118 -0
  231. package/linthost/rules_ts_no_unnecessary_template_expression.go +178 -0
  232. package/linthost/rules_ts_no_unnecessary_type_arguments.go +234 -0
  233. package/linthost/rules_ts_no_unnecessary_type_assertion.go +157 -0
  234. package/linthost/rules_ts_no_unsafe_argument.go +82 -0
  235. package/linthost/rules_ts_no_unsafe_assignment.go +102 -0
  236. package/linthost/rules_ts_no_unsafe_call.go +82 -0
  237. package/linthost/rules_ts_no_unsafe_enum_comparison.go +235 -0
  238. package/linthost/rules_ts_no_unsafe_member_access.go +58 -0
  239. package/linthost/rules_ts_no_unsafe_return.go +126 -0
  240. package/linthost/rules_ts_no_unsafe_unary_minus.go +81 -0
  241. package/linthost/rules_ts_no_useless_constructor.go +52 -0
  242. package/linthost/rules_ts_non_nullable_type_assertion_style.go +108 -0
  243. package/linthost/rules_ts_parameter_properties.go +38 -0
  244. package/linthost/rules_ts_prefer_find.go +178 -0
  245. package/linthost/rules_ts_prefer_includes.go +255 -0
  246. package/linthost/rules_ts_prefer_nullish_coalescing.go +104 -0
  247. package/linthost/rules_ts_prefer_optional_chain.go +228 -0
  248. package/linthost/rules_ts_prefer_promise_reject_errors.go +176 -0
  249. package/linthost/rules_ts_prefer_readonly.go +73 -0
  250. package/linthost/rules_ts_prefer_reduce_type_parameter.go +116 -0
  251. package/linthost/rules_ts_prefer_regexp_exec.go +122 -0
  252. package/linthost/rules_ts_prefer_return_this_type.go +135 -0
  253. package/linthost/rules_ts_prefer_string_starts_ends_with.go +360 -0
  254. package/linthost/rules_ts_promise_function_async.go +77 -0
  255. package/linthost/rules_ts_related_getter_setter_pairs.go +113 -0
  256. package/linthost/rules_ts_require_array_sort_compare.go +96 -0
  257. package/linthost/rules_ts_restrict_plus_operands.go +127 -0
  258. package/linthost/rules_ts_restrict_template_expressions.go +95 -0
  259. package/linthost/rules_ts_simple.go +387 -0
  260. package/linthost/rules_ts_sort_type_constituents.go +144 -0
  261. package/linthost/rules_ts_strict_boolean_expressions.go +157 -0
  262. package/linthost/rules_ts_switch_exhaustiveness_check.go +147 -0
  263. package/linthost/rules_ts_unbound_method.go +126 -0
  264. package/linthost/rules_tsdoc.go +136 -0
  265. package/linthost/rules_unicorn_better_regex.go +27 -0
  266. package/linthost/rules_unicorn_catch_error_name.go +46 -0
  267. package/linthost/rules_unicorn_consistent_assert.go +47 -0
  268. package/linthost/rules_unicorn_consistent_date_clone.go +54 -0
  269. package/linthost/rules_unicorn_consistent_destructuring.go +25 -0
  270. package/linthost/rules_unicorn_consistent_empty_array_spread.go +62 -0
  271. package/linthost/rules_unicorn_consistent_existence_index_check.go +80 -0
  272. package/linthost/rules_unicorn_consistent_function_scoping.go +25 -0
  273. package/linthost/rules_unicorn_consistent_template_literal_escape.go +25 -0
  274. package/linthost/rules_unicorn_custom_error_definition.go +138 -0
  275. package/linthost/rules_unicorn_empty_brace_spaces.go +73 -0
  276. package/linthost/rules_unicorn_error_message.go +64 -0
  277. package/linthost/rules_unicorn_escape_case.go +51 -0
  278. package/linthost/rules_unicorn_expiring_todo_comments.go +78 -0
  279. package/linthost/rules_unicorn_explicit_length_check.go +88 -0
  280. package/linthost/rules_unicorn_filename_case.go +29 -0
  281. package/linthost/rules_unicorn_import_style.go +28 -0
  282. package/linthost/rules_unicorn_isolated_functions.go +29 -0
  283. package/linthost/rules_unicorn_new_for_builtins.go +87 -0
  284. package/linthost/rules_unicorn_no_abusive_eslint_disable.go +63 -0
  285. package/linthost/rules_unicorn_no_accessor_recursion.go +115 -0
  286. package/linthost/rules_unicorn_no_anonymous_default_export.go +74 -0
  287. package/linthost/rules_unicorn_no_array_callback_reference.go +65 -0
  288. package/linthost/rules_unicorn_no_array_for_each.go +40 -0
  289. package/linthost/rules_unicorn_no_array_method_this_argument.go +61 -0
  290. package/linthost/rules_unicorn_no_array_reduce.go +41 -0
  291. package/linthost/rules_unicorn_no_array_reverse.go +44 -0
  292. package/linthost/rules_unicorn_no_array_sort.go +43 -0
  293. package/linthost/rules_unicorn_no_await_expression_member.go +40 -0
  294. package/linthost/rules_unicorn_no_await_in_promise_methods.go +69 -0
  295. package/linthost/rules_unicorn_no_console_spaces.go +61 -0
  296. package/linthost/rules_unicorn_no_document_cookie.go +41 -0
  297. package/linthost/rules_unicorn_no_empty_file.go +44 -0
  298. package/linthost/rules_unicorn_no_for_loop.go +102 -0
  299. package/linthost/rules_unicorn_no_hex_escape.go +42 -0
  300. package/linthost/rules_unicorn_no_immediate_mutation.go +90 -0
  301. package/linthost/rules_unicorn_no_instanceof_builtins.go +66 -0
  302. package/linthost/rules_unicorn_no_invalid_fetch_options.go +79 -0
  303. package/linthost/rules_unicorn_no_invalid_remove_event_listener.go +51 -0
  304. package/linthost/rules_unicorn_no_keyword_prefix.go +101 -0
  305. package/linthost/rules_unicorn_no_lonely_if.go +44 -0
  306. package/linthost/rules_unicorn_no_magic_array_flat_depth.go +51 -0
  307. package/linthost/rules_unicorn_no_named_default.go +54 -0
  308. package/linthost/rules_unicorn_no_negated_condition.go +85 -0
  309. package/linthost/rules_unicorn_no_negation_in_equality_check.go +50 -0
  310. package/linthost/rules_unicorn_no_nested_ternary.go +43 -0
  311. package/linthost/rules_unicorn_no_new_array.go +30 -0
  312. package/linthost/rules_unicorn_no_new_buffer.go +31 -0
  313. package/linthost/rules_unicorn_no_null.go +24 -0
  314. package/linthost/rules_unicorn_no_object_as_default_parameter.go +48 -0
  315. package/linthost/rules_unicorn_no_process_exit.go +43 -0
  316. package/linthost/rules_unicorn_no_single_promise_in_promise_methods.go +59 -0
  317. package/linthost/rules_unicorn_no_static_only_class.go +56 -0
  318. package/linthost/rules_unicorn_no_thenable.go +74 -0
  319. package/linthost/rules_unicorn_no_this_assignment.go +35 -0
  320. package/linthost/rules_unicorn_no_typeof_undefined.go +58 -0
  321. package/linthost/rules_unicorn_no_unnecessary_array_flat_depth.go +49 -0
  322. package/linthost/rules_unicorn_no_unnecessary_array_splice_count.go +70 -0
  323. package/linthost/rules_unicorn_no_unnecessary_await.go +51 -0
  324. package/linthost/rules_unicorn_no_unnecessary_polyfills.go +32 -0
  325. package/linthost/rules_unicorn_no_unnecessary_slice_end.go +48 -0
  326. package/linthost/rules_unicorn_no_unreadable_array_destructuring.go +115 -0
  327. package/linthost/rules_unicorn_no_unreadable_iife.go +50 -0
  328. package/linthost/rules_unicorn_no_unused_properties.go +30 -0
  329. package/linthost/rules_unicorn_no_useless_collection_argument.go +63 -0
  330. package/linthost/rules_unicorn_no_useless_error_capture_stack_trace.go +46 -0
  331. package/linthost/rules_unicorn_no_useless_fallback_in_spread.go +81 -0
  332. package/linthost/rules_unicorn_no_useless_iterator_to_array.go +72 -0
  333. package/linthost/rules_unicorn_no_useless_length_check.go +144 -0
  334. package/linthost/rules_unicorn_no_useless_promise_resolve_reject.go +81 -0
  335. package/linthost/rules_unicorn_no_useless_spread.go +67 -0
  336. package/linthost/rules_unicorn_no_useless_switch_case.go +55 -0
  337. package/linthost/rules_unicorn_no_useless_undefined.go +55 -0
  338. package/linthost/rules_unicorn_no_zero_fractions.go +52 -0
  339. package/linthost/rules_unicorn_number_literal_case.go +69 -0
  340. package/linthost/rules_unicorn_numeric_separators_style.go +75 -0
  341. package/linthost/rules_unicorn_prefer_add_event_listener.go +66 -0
  342. package/linthost/rules_unicorn_prefer_array_find.go +51 -0
  343. package/linthost/rules_unicorn_prefer_array_flat.go +52 -0
  344. package/linthost/rules_unicorn_prefer_array_flat_map.go +63 -0
  345. package/linthost/rules_unicorn_prefer_array_index_of.go +147 -0
  346. package/linthost/rules_unicorn_prefer_array_some.go +67 -0
  347. package/linthost/rules_unicorn_prefer_at.go +77 -0
  348. package/linthost/rules_unicorn_prefer_bigint_literals.go +77 -0
  349. package/linthost/rules_unicorn_prefer_blob_reading_methods.go +44 -0
  350. package/linthost/rules_unicorn_prefer_class_fields.go +93 -0
  351. package/linthost/rules_unicorn_prefer_classlist_toggle.go +120 -0
  352. package/linthost/rules_unicorn_prefer_code_point.go +49 -0
  353. package/linthost/rules_unicorn_prefer_date_now.go +78 -0
  354. package/linthost/rules_unicorn_prefer_default_parameters.go +144 -0
  355. package/linthost/rules_unicorn_prefer_dom_node_append.go +40 -0
  356. package/linthost/rules_unicorn_prefer_dom_node_dataset.go +55 -0
  357. package/linthost/rules_unicorn_prefer_dom_node_remove.go +41 -0
  358. package/linthost/rules_unicorn_prefer_dom_node_text_content.go +37 -0
  359. package/linthost/rules_unicorn_prefer_event_target.go +36 -0
  360. package/linthost/rules_unicorn_prefer_export_from.go +129 -0
  361. package/linthost/rules_unicorn_prefer_global_this.go +127 -0
  362. package/linthost/rules_unicorn_prefer_import_meta_properties.go +66 -0
  363. package/linthost/rules_unicorn_prefer_includes.go +149 -0
  364. package/linthost/rules_unicorn_prefer_json_parse_buffer.go +65 -0
  365. package/linthost/rules_unicorn_prefer_keyboard_event_key.go +38 -0
  366. package/linthost/rules_unicorn_prefer_logical_operator_over_ternary.go +48 -0
  367. package/linthost/rules_unicorn_prefer_math_min_max.go +60 -0
  368. package/linthost/rules_unicorn_prefer_math_trunc.go +62 -0
  369. package/linthost/rules_unicorn_prefer_modern_dom_apis.go +47 -0
  370. package/linthost/rules_unicorn_prefer_modern_math_apis.go +70 -0
  371. package/linthost/rules_unicorn_prefer_module.go +50 -0
  372. package/linthost/rules_unicorn_prefer_native_coercion_functions.go +114 -0
  373. package/linthost/rules_unicorn_prefer_negative_index.go +74 -0
  374. package/linthost/rules_unicorn_prefer_node_protocol.go +122 -0
  375. package/linthost/rules_unicorn_prefer_number_properties.go +88 -0
  376. package/linthost/rules_unicorn_prefer_object_from_entries.go +55 -0
  377. package/linthost/rules_unicorn_prefer_optional_catch_binding.go +62 -0
  378. package/linthost/rules_unicorn_prefer_prototype_methods.go +54 -0
  379. package/linthost/rules_unicorn_prefer_query_selector.go +56 -0
  380. package/linthost/rules_unicorn_prefer_reflect_apply.go +36 -0
  381. package/linthost/rules_unicorn_prefer_regexp_test_rule.go +80 -0
  382. package/linthost/rules_unicorn_prefer_response_static_json.go +53 -0
  383. package/linthost/rules_unicorn_prefer_set_has.go +42 -0
  384. package/linthost/rules_unicorn_prefer_set_size.go +48 -0
  385. package/linthost/rules_unicorn_prefer_simple_condition_first.go +34 -0
  386. package/linthost/rules_unicorn_prefer_single_call.go +96 -0
  387. package/linthost/rules_unicorn_prefer_spread.go +51 -0
  388. package/linthost/rules_unicorn_prefer_string_raw.go +43 -0
  389. package/linthost/rules_unicorn_prefer_string_replace_all.go +95 -0
  390. package/linthost/rules_unicorn_prefer_string_slice.go +43 -0
  391. package/linthost/rules_unicorn_prefer_string_starts_ends_with.go +148 -0
  392. package/linthost/rules_unicorn_prefer_string_trim_start_end.go +48 -0
  393. package/linthost/rules_unicorn_prefer_structured_clone.go +71 -0
  394. package/linthost/rules_unicorn_prefer_switch.go +103 -0
  395. package/linthost/rules_unicorn_prefer_ternary.go +71 -0
  396. package/linthost/rules_unicorn_prefer_top_level_await.go +72 -0
  397. package/linthost/rules_unicorn_prefer_type_error.go +127 -0
  398. package/linthost/rules_unicorn_prevent_abbreviations.go +127 -0
  399. package/linthost/rules_unicorn_relative_url_style.go +49 -0
  400. package/linthost/rules_unicorn_require_array_join_separator.go +45 -0
  401. package/linthost/rules_unicorn_require_module_attributes.go +54 -0
  402. package/linthost/rules_unicorn_require_module_specifiers.go +55 -0
  403. package/linthost/rules_unicorn_require_number_to_fixed_digits_argument.go +43 -0
  404. package/linthost/rules_unicorn_require_post_message_target_origin.go +44 -0
  405. package/linthost/rules_unicorn_string_content.go +27 -0
  406. package/linthost/rules_unicorn_switch_case_braces.go +42 -0
  407. package/linthost/rules_unicorn_switch_case_break_position.go +31 -0
  408. package/linthost/rules_unicorn_template_indent.go +28 -0
  409. package/linthost/rules_unicorn_text_encoding_identifier_case.go +72 -0
  410. package/linthost/rules_unicorn_throw_new_error.go +61 -0
  411. package/linthost/rules_var.go +4 -4
  412. package/linthost/rules_vitest.go +568 -0
  413. package/package.json +3 -3
  414. package/plugin/main.go +49 -3
  415. package/rule/astutil/astutil.go +10 -3
  416. package/rule/rule.go +12 -10
  417. package/src/defaultFormat.ts +11 -8
  418. package/src/index.ts +40 -16
  419. package/src/structures/ITtscLintConfig.ts +12 -6
  420. package/src/structures/{ITtscLintFormatConfig.ts → ITtscLintFormat.ts} +2 -2
  421. package/src/structures/TtscLintRuleSetting.ts +55 -0
  422. package/src/structures/index.ts +3 -4
  423. package/src/structures/rules/ITtscLintBoundariesRuleOptions.ts +128 -0
  424. package/src/structures/rules/ITtscLintBoundariesRules.ts +95 -0
  425. package/src/structures/rules/ITtscLintContributorRules.ts +21 -0
  426. package/src/structures/rules/ITtscLintCoreRules.ts +1406 -0
  427. package/src/structures/rules/ITtscLintCypressRuleOptions.ts +18 -0
  428. package/src/structures/rules/ITtscLintCypressRules.ts +145 -0
  429. package/src/structures/rules/ITtscLintFunctionalRuleOptions.ts +213 -0
  430. package/src/structures/rules/ITtscLintFunctionalRules.ts +202 -0
  431. package/src/structures/rules/ITtscLintJestRules.ts +220 -0
  432. package/src/structures/rules/ITtscLintJsdocRules.ts +153 -0
  433. package/src/structures/rules/ITtscLintJsxA11yRules.ts +339 -0
  434. package/src/structures/rules/ITtscLintNextjsRules.ts +206 -0
  435. package/src/structures/rules/ITtscLintPlaywrightRules.ts +361 -0
  436. package/src/structures/rules/ITtscLintPromiseRules.ts +205 -0
  437. package/src/structures/rules/ITtscLintReactPerfRuleOptions.ts +19 -0
  438. package/src/structures/rules/ITtscLintReactPerfRules.ts +55 -0
  439. package/src/structures/rules/ITtscLintReactRuleOptions.ts +43 -0
  440. package/src/structures/rules/ITtscLintReactRules.ts +321 -0
  441. package/src/structures/rules/ITtscLintRegexpRules.ts +212 -0
  442. package/src/structures/rules/ITtscLintRuleOptionsMap.ts +89 -0
  443. package/src/structures/rules/ITtscLintRules.ts +77 -0
  444. package/src/structures/rules/ITtscLintSecurityRules.ts +162 -0
  445. package/src/structures/rules/ITtscLintSolidRules.ts +202 -0
  446. package/src/structures/rules/ITtscLintStorybookRuleOptions.ts +23 -0
  447. package/src/structures/rules/ITtscLintStorybookRules.ts +193 -0
  448. package/src/structures/rules/ITtscLintTanstackQueryRules.ts +102 -0
  449. package/src/structures/rules/ITtscLintTestingLibraryRuleOptions.ts +24 -0
  450. package/src/structures/rules/ITtscLintTestingLibraryRules.ts +342 -0
  451. package/src/structures/rules/ITtscLintTypeScriptRules.ts +1230 -0
  452. package/src/structures/rules/ITtscLintUnicornRules.ts +1143 -0
  453. package/src/structures/rules/ITtscLintVitestRules.ts +154 -0
  454. package/src/structures/rules/index.ts +31 -0
  455. package/lib/structures/ITtscLintFormatConfig.js.map +0 -1
  456. package/lib/structures/TtscLintRule.d.ts +0 -17
  457. package/lib/structures/TtscLintRule.js.map +0 -1
  458. package/lib/structures/TtscLintRuleMap.d.ts +0 -46
  459. package/lib/structures/TtscLintRuleMap.js.map +0 -1
  460. package/lib/structures/TtscLintRuleOptions.d.ts +0 -137
  461. package/lib/structures/TtscLintRuleOptions.js.map +0 -1
  462. package/src/structures/TtscLintRule.ts +0 -160
  463. package/src/structures/TtscLintRuleMap.ts +0 -55
  464. package/src/structures/TtscLintRuleOptions.ts +0 -151
@@ -11,10 +11,10 @@ import (
11
11
  shimast "github.com/microsoft/typescript-go/shim/ast"
12
12
  )
13
13
 
14
- // no-confusing-non-null-assertion: `a! == b` reads ambiguously.
14
+ // noConfusingNonNullAssertion: `a! == b` reads ambiguously.
15
15
  type noConfusingNonNullAssertion struct{}
16
16
 
17
- func (noConfusingNonNullAssertion) Name() string { return "no-confusing-non-null-assertion" }
17
+ func (noConfusingNonNullAssertion) Name() string { return "typescript/no-confusing-non-null-assertion" }
18
18
  func (noConfusingNonNullAssertion) Visits() []shimast.Kind {
19
19
  return []shimast.Kind{shimast.KindBinaryExpression}
20
20
  }
@@ -37,11 +37,11 @@ func (noConfusingNonNullAssertion) Check(ctx *Context, node *shimast.Node) {
37
37
  }
38
38
  }
39
39
 
40
- // no-duplicate-enum-values: `enum E { A = 1, B = 1 }` — duplicate values
40
+ // noDuplicateEnumValues: `enum E { A = 1, B = 1 }` — duplicate values
41
41
  // silently collapse.
42
42
  type noDuplicateEnumValues struct{}
43
43
 
44
- func (noDuplicateEnumValues) Name() string { return "no-duplicate-enum-values" }
44
+ func (noDuplicateEnumValues) Name() string { return "typescript/no-duplicate-enum-values" }
45
45
  func (noDuplicateEnumValues) Visits() []shimast.Kind {
46
46
  return []shimast.Kind{shimast.KindEnumDeclaration}
47
47
  }
@@ -77,13 +77,13 @@ func (noDuplicateEnumValues) Check(ctx *Context, node *shimast.Node) {
77
77
  }
78
78
  }
79
79
 
80
- // no-mixed-enums: forbid enums that mix numeric and string member shapes.
80
+ // noMixedEnums: forbid enums that mix numeric and string member shapes.
81
81
  // A single enum with `{ A, B = "two" }` produces broken reverse mappings
82
82
  // and surprising assignability. typescript-eslint recommended:
83
83
  // https://typescript-eslint.io/rules/no-mixed-enums/
84
84
  type noMixedEnums struct{}
85
85
 
86
- func (noMixedEnums) Name() string { return "no-mixed-enums" }
86
+ func (noMixedEnums) Name() string { return "typescript/no-mixed-enums" }
87
87
  func (noMixedEnums) Visits() []shimast.Kind {
88
88
  return []shimast.Kind{shimast.KindEnumDeclaration}
89
89
  }
@@ -137,10 +137,10 @@ func (noMixedEnums) Check(ctx *Context, node *shimast.Node) {
137
137
  }
138
138
  }
139
139
 
140
- // no-extra-non-null-assertion: `a!!` / `a!?.b` collapses two assertions.
140
+ // noExtraNonNullAssertion: `a!!` / `a!?.b` collapses two assertions.
141
141
  type noExtraNonNullAssertion struct{}
142
142
 
143
- func (noExtraNonNullAssertion) Name() string { return "no-extra-non-null-assertion" }
143
+ func (noExtraNonNullAssertion) Name() string { return "typescript/no-extra-non-null-assertion" }
144
144
  func (noExtraNonNullAssertion) Visits() []shimast.Kind {
145
145
  return []shimast.Kind{shimast.KindNonNullExpression}
146
146
  }
@@ -169,11 +169,11 @@ func (noExtraNonNullAssertion) Check(ctx *Context, node *shimast.Node) {
169
169
  )
170
170
  }
171
171
 
172
- // no-non-null-asserted-optional-chain: `foo?.bar!` — the chain produces
172
+ // noNonNullAssertedOptionalChain: `foo?.bar!` — the chain produces
173
173
  // undefined; asserting non-null on the whole chain defeats the chain.
174
174
  type noNonNullAssertedOptionalChain struct{}
175
175
 
176
- func (noNonNullAssertedOptionalChain) Name() string { return "no-non-null-asserted-optional-chain" }
176
+ func (noNonNullAssertedOptionalChain) Name() string { return "typescript/no-non-null-asserted-optional-chain" }
177
177
  func (noNonNullAssertedOptionalChain) Visits() []shimast.Kind {
178
178
  return []shimast.Kind{shimast.KindNonNullExpression}
179
179
  }
@@ -224,12 +224,12 @@ func containsOptionalChain(node *shimast.Node) bool {
224
224
  return false
225
225
  }
226
226
 
227
- // no-misused-new: declaring a `new` signature on a non-class interface
227
+ // noMisusedNew: declaring a `new` signature on a non-class interface
228
228
  // or a `constructor` method on an interface — these don't do what
229
229
  // authors expect.
230
230
  type noMisusedNew struct{}
231
231
 
232
- func (noMisusedNew) Name() string { return "no-misused-new" }
232
+ func (noMisusedNew) Name() string { return "typescript/no-misused-new" }
233
233
  func (noMisusedNew) Visits() []shimast.Kind {
234
234
  return []shimast.Kind{shimast.KindInterfaceDeclaration, shimast.KindTypeAliasDeclaration}
235
235
  }
@@ -257,11 +257,109 @@ func (noMisusedNew) Check(ctx *Context, node *shimast.Node) {
257
257
  }
258
258
  }
259
259
 
260
- // prefer-enum-initializers: every enum member should have an explicit
260
+ // noUnnecessaryParameterPropertyAssignment: parameter properties already
261
+ // assign the constructor argument to `this.<name>` before the body runs.
262
+ // A body-level `this.x = x` immediately repeats that initialization.
263
+ type noUnnecessaryParameterPropertyAssignment struct{}
264
+
265
+ func (noUnnecessaryParameterPropertyAssignment) Name() string {
266
+ return "typescript/no-unnecessary-parameter-property-assignment"
267
+ }
268
+ func (noUnnecessaryParameterPropertyAssignment) Visits() []shimast.Kind {
269
+ return []shimast.Kind{shimast.KindConstructor}
270
+ }
271
+ func (noUnnecessaryParameterPropertyAssignment) Check(ctx *Context, node *shimast.Node) {
272
+ parameterProperties := map[string]bool{}
273
+ for _, param := range node.Parameters() {
274
+ name, ok := parameterPropertyName(param)
275
+ if ok {
276
+ parameterProperties[name] = true
277
+ }
278
+ }
279
+ if len(parameterProperties) == 0 {
280
+ return
281
+ }
282
+ body := node.Body()
283
+ if body == nil || body.Kind != shimast.KindBlock {
284
+ return
285
+ }
286
+ block := body.AsBlock()
287
+ if block == nil || block.Statements == nil {
288
+ return
289
+ }
290
+ assigned := map[string]bool{}
291
+ for _, stmt := range block.Statements.Nodes {
292
+ property, value, ok := thisPropertyAssignment(stmt)
293
+ if !ok {
294
+ continue
295
+ }
296
+ if parameterProperties[property] && !assigned[property] && value == property {
297
+ ctx.Report(stmt, "This assignment repeats the constructor parameter property initialization.")
298
+ }
299
+ assigned[property] = true
300
+ }
301
+ }
302
+
303
+ func parameterPropertyName(param *shimast.Node) (string, bool) {
304
+ if param == nil || param.Kind != shimast.KindParameter {
305
+ return "", false
306
+ }
307
+ if !isParameterProperty(param) {
308
+ return "", false
309
+ }
310
+ decl := param.AsParameterDeclaration()
311
+ if decl == nil {
312
+ return "", false
313
+ }
314
+ name := identifierText(decl.Name())
315
+ return name, name != ""
316
+ }
317
+
318
+ func isParameterProperty(param *shimast.Node) bool {
319
+ return hasModifier(param, shimast.KindPublicKeyword) ||
320
+ hasModifier(param, shimast.KindPrivateKeyword) ||
321
+ hasModifier(param, shimast.KindProtectedKeyword) ||
322
+ hasModifier(param, shimast.KindReadonlyKeyword) ||
323
+ hasModifier(param, shimast.KindOverrideKeyword)
324
+ }
325
+
326
+ func thisPropertyAssignment(stmt *shimast.Node) (property string, value string, ok bool) {
327
+ if stmt == nil || stmt.Kind != shimast.KindExpressionStatement {
328
+ return "", "", false
329
+ }
330
+ exprStmt := stmt.AsExpressionStatement()
331
+ if exprStmt == nil || exprStmt.Expression == nil {
332
+ return "", "", false
333
+ }
334
+ expr := stripParens(exprStmt.Expression)
335
+ if expr == nil || expr.Kind != shimast.KindBinaryExpression {
336
+ return "", "", false
337
+ }
338
+ binary := expr.AsBinaryExpression()
339
+ if binary == nil || binary.OperatorToken == nil || binary.OperatorToken.Kind != shimast.KindEqualsToken {
340
+ return "", "", false
341
+ }
342
+ left := stripParens(binary.Left)
343
+ if left == nil || left.Kind != shimast.KindPropertyAccessExpression {
344
+ return "", "", false
345
+ }
346
+ access := left.AsPropertyAccessExpression()
347
+ if access == nil || access.Expression == nil || access.Expression.Kind != shimast.KindThisKeyword {
348
+ return "", "", false
349
+ }
350
+ property = identifierText(access.Name())
351
+ value = identifierText(stripParens(binary.Right))
352
+ if property == "" {
353
+ return "", "", false
354
+ }
355
+ return property, value, true
356
+ }
357
+
358
+ // preferEnumInitializers: every enum member should have an explicit
261
359
  // initializer (avoids order-dependent values).
262
360
  type preferEnumInitializers struct{}
263
361
 
264
- func (preferEnumInitializers) Name() string { return "prefer-enum-initializers" }
362
+ func (preferEnumInitializers) Name() string { return "typescript/prefer-enum-initializers" }
265
363
  func (preferEnumInitializers) Visits() []shimast.Kind {
266
364
  return []shimast.Kind{shimast.KindEnumDeclaration}
267
365
  }
@@ -281,7 +379,7 @@ func (preferEnumInitializers) Check(ctx *Context, node *shimast.Node) {
281
379
  }
282
380
  }
283
381
 
284
- // prefer-for-of: `for (let i = 0; i < arr.length; i++) { use(arr[i]) }`
382
+ // preferForOf: `for (let i = 0; i < arr.length; i++) { use(arr[i]) }`
285
383
  // can usually be replaced with `for (const x of arr) { use(x); }`.
286
384
  type preferForOf struct{}
287
385
 
@@ -351,13 +449,13 @@ func isCounterIncrement(node *shimast.Node, counter string) bool {
351
449
  return false
352
450
  }
353
451
 
354
- // prefer-function-type: a single-call-signature interface or type alias
452
+ // preferFunctionType: a single-call-signature interface or type alias
355
453
  // is more readably written as a function type.
356
454
  //
357
455
  // interface F { (x: number): string } -> type F = (x: number) => string
358
456
  type preferFunctionType struct{}
359
457
 
360
- func (preferFunctionType) Name() string { return "prefer-function-type" }
458
+ func (preferFunctionType) Name() string { return "typescript/prefer-function-type" }
361
459
  func (preferFunctionType) Visits() []shimast.Kind {
362
460
  return []shimast.Kind{shimast.KindInterfaceDeclaration}
363
461
  }
@@ -376,11 +474,30 @@ func (preferFunctionType) Check(ctx *Context, node *shimast.Node) {
376
474
  ctx.Report(node, "Interface only has a call signature; use 'type' alias and function type instead.")
377
475
  }
378
476
 
379
- // prefer-namespace-keyword: `module Foo {}` (TS namespace via `module`
477
+ // methodSignatureStyle: prefer function-property signatures over method
478
+ // shorthand in interfaces and type literals. This implements the default
479
+ // @typescript-eslint mode (`property`) as a diagnostic-only rule.
480
+ type methodSignatureStyle struct{}
481
+
482
+ func (methodSignatureStyle) Name() string { return "typescript/method-signature-style" }
483
+ func (methodSignatureStyle) Visits() []shimast.Kind {
484
+ return []shimast.Kind{shimast.KindMethodSignature}
485
+ }
486
+ func (methodSignatureStyle) Check(ctx *Context, node *shimast.Node) {
487
+ if node.Parent == nil {
488
+ return
489
+ }
490
+ switch node.Parent.Kind {
491
+ case shimast.KindInterfaceDeclaration, shimast.KindTypeLiteral:
492
+ ctx.Report(node, "Use a function-property signature instead of a method signature.")
493
+ }
494
+ }
495
+
496
+ // preferNamespaceKeyword: `module Foo {}` (TS namespace via `module`
380
497
  // keyword) → `namespace Foo {}`.
381
498
  type preferNamespaceKeyword struct{}
382
499
 
383
- func (preferNamespaceKeyword) Name() string { return "prefer-namespace-keyword" }
500
+ func (preferNamespaceKeyword) Name() string { return "typescript/prefer-namespace-keyword" }
384
501
  func (preferNamespaceKeyword) Visits() []shimast.Kind {
385
502
  return []shimast.Kind{shimast.KindModuleDeclaration}
386
503
  }
@@ -408,11 +525,11 @@ func (preferNamespaceKeyword) Check(ctx *Context, node *shimast.Node) {
408
525
  )
409
526
  }
410
527
 
411
- // triple-slash-reference: `/// <reference path="..." />` directives.
528
+ // tripleSlashReference: `/// <reference path="..." />` directives.
412
529
  // Discouraged in modern code in favor of `import`.
413
530
  type tripleSlashReference struct{}
414
531
 
415
- func (tripleSlashReference) Name() string { return "triple-slash-reference" }
532
+ func (tripleSlashReference) Name() string { return "typescript/triple-slash-reference" }
416
533
  func (tripleSlashReference) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindSourceFile} }
417
534
  func (tripleSlashReference) Check(ctx *Context, node *shimast.Node) {
418
535
  if ctx.File == nil {
@@ -426,10 +543,10 @@ func (tripleSlashReference) Check(ctx *Context, node *shimast.Node) {
426
543
  }
427
544
  }
428
545
 
429
- // no-array-delete: `delete arr[0]` leaves a sparse hole. Use `splice`.
546
+ // noArrayDelete: `delete arr[0]` leaves a sparse hole. Use `splice`.
430
547
  type noArrayDelete struct{}
431
548
 
432
- func (noArrayDelete) Name() string { return "no-array-delete" }
549
+ func (noArrayDelete) Name() string { return "typescript/no-array-delete" }
433
550
  func (noArrayDelete) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindDeleteExpression} }
434
551
  func (noArrayDelete) Check(ctx *Context, node *shimast.Node) {
435
552
  del := node.AsDeleteExpression()
@@ -451,7 +568,7 @@ func (noArrayDelete) Check(ctx *Context, node *shimast.Node) {
451
568
  }
452
569
  }
453
570
 
454
- // consistent-type-imports: `import { Foo } from "./types"` where Foo is
571
+ // consistentTypeImports: `import { Foo } from "./types"` where Foo is
455
572
  // only used as a type → `import type { Foo } from "./types"`. We
456
573
  // approximate by flagging every `import type` candidate where the
457
574
  // specifier appears in a type-only context inside the file.
@@ -462,7 +579,7 @@ func (noArrayDelete) Check(ctx *Context, node *shimast.Node) {
462
579
  // common case.
463
580
  type consistentTypeImports struct{}
464
581
 
465
- func (consistentTypeImports) Name() string { return "consistent-type-imports" }
582
+ func (consistentTypeImports) Name() string { return "typescript/consistent-type-imports" }
466
583
  func (consistentTypeImports) Visits() []shimast.Kind {
467
584
  return []shimast.Kind{shimast.KindImportDeclaration}
468
585
  }
@@ -549,12 +666,12 @@ func allUsesAreTypeOnly(root *shimast.Node, names []string) bool {
549
666
  return allOk
550
667
  }
551
668
 
552
- // no-empty-object-type: `interface Foo {}` / `type Foo = {}`. ESLint
669
+ // noEmptyObjectType: `interface Foo {}` / `type Foo = {}`. ESLint
553
670
  // flags empty types because they're equivalent to `unknown` (everything
554
671
  // satisfies `{}`).
555
672
  type noEmptyObjectType struct{}
556
673
 
557
- func (noEmptyObjectType) Name() string { return "no-empty-object-type" }
674
+ func (noEmptyObjectType) Name() string { return "typescript/no-empty-object-type" }
558
675
  func (noEmptyObjectType) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindTypeLiteral} }
559
676
  func (noEmptyObjectType) Check(ctx *Context, node *shimast.Node) {
560
677
  lit := node.AsTypeLiteralNode()
@@ -566,10 +683,10 @@ func (noEmptyObjectType) Check(ctx *Context, node *shimast.Node) {
566
683
  }
567
684
  }
568
685
 
569
- // array-type: `Array<T>` vs `T[]`. ESLint default mode prefers `T[]`.
686
+ // arrayType: `Array<T>` vs `T[]`. ESLint default mode prefers `T[]`.
570
687
  type arrayType struct{}
571
688
 
572
- func (arrayType) Name() string { return "array-type" }
689
+ func (arrayType) Name() string { return "typescript/array-type" }
573
690
  func (arrayType) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindTypeReference} }
574
691
  func (arrayType) Check(ctx *Context, node *shimast.Node) {
575
692
  ref := node.AsTypeReferenceNode()
@@ -590,11 +707,11 @@ func (arrayType) Check(ctx *Context, node *shimast.Node) {
590
707
  }
591
708
  }
592
709
 
593
- // consistent-indexed-object-style: `{ [key: string]: T }` vs
710
+ // consistentIndexedObjectStyle: `{ [key: string]: T }` vs
594
711
  // `Record<string, T>`. ESLint default prefers `Record`.
595
712
  type consistentIndexedObjectStyle struct{}
596
713
 
597
- func (consistentIndexedObjectStyle) Name() string { return "consistent-indexed-object-style" }
714
+ func (consistentIndexedObjectStyle) Name() string { return "typescript/consistent-indexed-object-style" }
598
715
  func (consistentIndexedObjectStyle) Visits() []shimast.Kind {
599
716
  return []shimast.Kind{shimast.KindTypeLiteral}
600
717
  }
@@ -611,17 +728,17 @@ func (consistentIndexedObjectStyle) Check(ctx *Context, node *shimast.Node) {
611
728
  }
612
729
 
613
730
  // no-explicit-any-rest-parameter — keeping this distinct from
614
- // no-explicit-any: rest parameters typed `...args: any[]` are common
731
+ // noExplicitAny: rest parameters typed `...args: any[]` are common
615
732
  // enough that users want to allow them; this rule lets them ban that
616
733
  // shape specifically.
617
734
  //
618
735
  // (Skipped: too narrow / overlaps with no-explicit-any.)
619
736
 
620
- // ban-tslint-comment: `// tslint:disable`. tslint is dead; comments
737
+ // banTslintComment: `// tslint:disable`. tslint is dead; comments
621
738
  // referencing it should be cleaned up.
622
739
  type banTslintComment struct{}
623
740
 
624
- func (banTslintComment) Name() string { return "ban-tslint-comment" }
741
+ func (banTslintComment) Name() string { return "typescript/ban-tslint-comment" }
625
742
  func (banTslintComment) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindSourceFile} }
626
743
  func (banTslintComment) Check(ctx *Context, node *shimast.Node) {
627
744
  if ctx.File == nil {
@@ -644,12 +761,12 @@ func (banTslintComment) Check(ctx *Context, node *shimast.Node) {
644
761
  }
645
762
  }
646
763
 
647
- // adjacent-overload-signatures: function/method overloads must be
764
+ // adjacentOverloadSignatures: function/method overloads must be
648
765
  // declared next to each other. ESLint catches the visual confusion
649
766
  // when overloads are interleaved with other members.
650
767
  type adjacentOverloadSignatures struct{}
651
768
 
652
- func (adjacentOverloadSignatures) Name() string { return "adjacent-overload-signatures" }
769
+ func (adjacentOverloadSignatures) Name() string { return "typescript/adjacent-overload-signatures" }
653
770
  func (adjacentOverloadSignatures) Visits() []shimast.Kind {
654
771
  return []shimast.Kind{shimast.KindInterfaceDeclaration, shimast.KindTypeLiteral, shimast.KindClassDeclaration, shimast.KindClassExpression, shimast.KindModuleBlock, shimast.KindSourceFile}
655
772
  }
@@ -764,9 +881,11 @@ func init() {
764
881
  Register(noExtraNonNullAssertion{})
765
882
  Register(noNonNullAssertedOptionalChain{})
766
883
  Register(noMisusedNew{})
884
+ Register(noUnnecessaryParameterPropertyAssignment{})
767
885
  Register(preferEnumInitializers{})
768
886
  Register(preferForOf{})
769
887
  Register(preferFunctionType{})
888
+ Register(methodSignatureStyle{})
770
889
  Register(preferNamespaceKeyword{})
771
890
  Register(tripleSlashReference{})
772
891
  Register(noArrayDelete{})
@@ -0,0 +1,218 @@
1
+ // typescript/no-base-to-string: a string-coercion context that
2
+ // resolves `toString` to the default `Object.prototype.toString`
3
+ // produces the useless `"[object Object]"` placeholder at runtime.
4
+ // typescript-eslint:
5
+ // https://typescript-eslint.io/rules/no-base-to-string/
6
+ //
7
+ // Type-aware. The rule visits the three shapes that implicitly coerce
8
+ // a value through `toString`:
9
+ //
10
+ // - `${x}` — every interpolated expression in a TemplateExpression;
11
+ // - `x + y` — when one operand is statically string-typed the other
12
+ // operand is coerced;
13
+ // - `String(x)` — explicit one-argument coercion.
14
+ //
15
+ // A type is "safely stringifiable" when it is a primitive-like type
16
+ // (`string`-/`number`-/`bigint`-/`boolean`-like, `null`, `undefined`),
17
+ // when the Checker reports it as `any` / `unknown` / `never` (those
18
+ // escape strict reasoning the same way `await-thenable` lets them
19
+ // pass), or when it overrides `toString` away from the global
20
+ // `Object` interface. Unions are safe only when every constituent is
21
+ // safe; intersections are safe when any constituent is safe.
22
+ package linthost
23
+
24
+ import (
25
+ shimast "github.com/microsoft/typescript-go/shim/ast"
26
+ shimchecker "github.com/microsoft/typescript-go/shim/checker"
27
+ )
28
+
29
+ type noBaseToString struct{}
30
+
31
+ func (noBaseToString) Name() string { return "typescript/no-base-to-string" }
32
+ func (noBaseToString) NeedsTypeChecker() bool {
33
+ return true
34
+ }
35
+ func (noBaseToString) Visits() []shimast.Kind {
36
+ return []shimast.Kind{
37
+ shimast.KindTemplateExpression,
38
+ shimast.KindBinaryExpression,
39
+ shimast.KindCallExpression,
40
+ }
41
+ }
42
+ func (noBaseToString) Check(ctx *Context, node *shimast.Node) {
43
+ if ctx.Checker == nil {
44
+ return
45
+ }
46
+ switch node.Kind {
47
+ case shimast.KindTemplateExpression:
48
+ expr := node.AsTemplateExpression()
49
+ if expr == nil || expr.TemplateSpans == nil {
50
+ return
51
+ }
52
+ for _, spanNode := range expr.TemplateSpans.Nodes {
53
+ span := spanNode.AsTemplateSpan()
54
+ if span == nil || span.Expression == nil {
55
+ continue
56
+ }
57
+ reportIfBaseToString(ctx, span.Expression)
58
+ }
59
+ case shimast.KindBinaryExpression:
60
+ bin := node.AsBinaryExpression()
61
+ if bin == nil || bin.OperatorToken == nil || bin.OperatorToken.Kind != shimast.KindPlusToken {
62
+ return
63
+ }
64
+ left := stripParens(bin.Left)
65
+ right := stripParens(bin.Right)
66
+ if left == nil || right == nil {
67
+ return
68
+ }
69
+ leftType := ctx.Checker.GetTypeAtLocation(left)
70
+ rightType := ctx.Checker.GetTypeAtLocation(right)
71
+ if isStringLikeType(leftType) {
72
+ if !isSafeToStringType(ctx.Checker, rightType) {
73
+ ctx.Report(right, baseToStringMessage)
74
+ }
75
+ } else if isStringLikeType(rightType) {
76
+ if !isSafeToStringType(ctx.Checker, leftType) {
77
+ ctx.Report(left, baseToStringMessage)
78
+ }
79
+ }
80
+ case shimast.KindCallExpression:
81
+ call := node.AsCallExpression()
82
+ if call == nil || call.Expression == nil || call.Arguments == nil {
83
+ return
84
+ }
85
+ if call.Expression.Kind != shimast.KindIdentifier || identifierText(call.Expression) != "String" {
86
+ return
87
+ }
88
+ if len(call.Arguments.Nodes) != 1 {
89
+ return
90
+ }
91
+ reportIfBaseToString(ctx, call.Arguments.Nodes[0])
92
+ }
93
+ }
94
+
95
+ const baseToStringMessage = "Value implicitly coerces to '[object Object]'. Override `toString` or pass an explicit string representation."
96
+
97
+ func reportIfBaseToString(ctx *Context, expr *shimast.Node) {
98
+ if expr == nil {
99
+ return
100
+ }
101
+ t := ctx.Checker.GetTypeAtLocation(expr)
102
+ if isSafeToStringType(ctx.Checker, t) {
103
+ return
104
+ }
105
+ ctx.Report(expr, baseToStringMessage)
106
+ }
107
+
108
+ // isStringLikeType reports whether t is provably string-typed (a
109
+ // literal, the primitive, a template-literal type, or any combination
110
+ // thereof). Used to decide whether the OTHER operand of a `+`
111
+ // expression is being coerced.
112
+ func isStringLikeType(t *shimchecker.Type) bool {
113
+ if t == nil {
114
+ return false
115
+ }
116
+ flags := t.Flags()
117
+ if flags&shimchecker.TypeFlagsStringLike != 0 {
118
+ return true
119
+ }
120
+ if flags&shimchecker.TypeFlagsUnion != 0 {
121
+ for _, part := range t.Types() {
122
+ if !isStringLikeType(part) {
123
+ return false
124
+ }
125
+ }
126
+ return true
127
+ }
128
+ return false
129
+ }
130
+
131
+ // isSafeToStringType reports whether `t` can be implicitly coerced to a
132
+ // string without producing the default `Object.prototype.toString`
133
+ // output. The shape mirrors `isAwaitable` in rules_promise.go: union
134
+ // constituents must all be safe; intersection constituents are safe
135
+ // when any one of them is. The `any` / `unknown` / `never` cases pass
136
+ // because flagging them would explode at generic-helper boundaries —
137
+ // the same conservatism `no-floating-promises` adopts.
138
+ func isSafeToStringType(checker *shimchecker.Checker, t *shimchecker.Type) bool {
139
+ if checker == nil || t == nil {
140
+ return true
141
+ }
142
+ flags := t.Flags()
143
+ if flags&(shimchecker.TypeFlagsAny|shimchecker.TypeFlagsUnknown|shimchecker.TypeFlagsNever) != 0 {
144
+ return true
145
+ }
146
+ if flags&(shimchecker.TypeFlagsStringLike|
147
+ shimchecker.TypeFlagsNumberLike|
148
+ shimchecker.TypeFlagsBigIntLike|
149
+ shimchecker.TypeFlagsBooleanLike|
150
+ shimchecker.TypeFlagsNull|
151
+ shimchecker.TypeFlagsUndefined) != 0 {
152
+ return true
153
+ }
154
+ if flags&shimchecker.TypeFlagsUnion != 0 {
155
+ for _, part := range t.Types() {
156
+ if !isSafeToStringType(checker, part) {
157
+ return false
158
+ }
159
+ }
160
+ return true
161
+ }
162
+ if flags&shimchecker.TypeFlagsIntersection != 0 {
163
+ for _, part := range t.Types() {
164
+ if isSafeToStringType(checker, part) {
165
+ return true
166
+ }
167
+ }
168
+ return false
169
+ }
170
+ return typeOverridesToString(checker, t)
171
+ }
172
+
173
+ // typeOverridesToString reports whether `t` carries a `toString` method
174
+ // that is NOT the default declaration on the global `Object` interface.
175
+ // The lib.es5.d.ts `Object` interface declares `toString(): string`; a
176
+ // custom override is what makes coercion meaningful at runtime. If no
177
+ // `toString` is reachable at all the type is treated as base — the
178
+ // only way to coerce it is the prototype-chain default.
179
+ func typeOverridesToString(checker *shimchecker.Checker, t *shimchecker.Type) bool {
180
+ prop := checker.GetPropertyOfType(t, "toString")
181
+ if prop == nil {
182
+ return false
183
+ }
184
+ for _, decl := range prop.Declarations {
185
+ if decl == nil {
186
+ continue
187
+ }
188
+ if !isObjectToStringDeclaration(decl) {
189
+ return true
190
+ }
191
+ }
192
+ return false
193
+ }
194
+
195
+ // isObjectToStringDeclaration reports whether `decl` is the
196
+ // `toString(): string` member that lives on the global `Object`
197
+ // interface in lib.es5.d.ts. Walking the parent chain stops at the
198
+ // nearest `interface Object {}` / `interface ObjectConstructor {}`
199
+ // declaration; anything else (Array, Date, Error, user classes, etc.)
200
+ // counts as a real override.
201
+ func isObjectToStringDeclaration(decl *shimast.Node) bool {
202
+ parent := decl.Parent
203
+ if parent == nil {
204
+ return false
205
+ }
206
+ if parent.Kind != shimast.KindInterfaceDeclaration {
207
+ return false
208
+ }
209
+ iface := parent.AsInterfaceDeclaration()
210
+ if iface == nil {
211
+ return false
212
+ }
213
+ return identifierText(iface.Name()) == "Object"
214
+ }
215
+
216
+ func init() {
217
+ Register(noBaseToString{})
218
+ }
@@ -0,0 +1,72 @@
1
+ // noConfusingVoidExpression reports `void X` operator uses placed in
2
+ // positions where the surrounding context expects a value. The `void`
3
+ // operator always evaluates to `undefined`, so threading it through a
4
+ // binary expression, ternary, call argument, initializer, or `return`
5
+ // statement is almost always a confusion between the operator and the
6
+ // `void` type.
7
+ //
8
+ // Allowed positions:
9
+ // - statement: `void x;`
10
+ // - arrow function concise body: `() => void x`
11
+ // - operand of an enclosing `void`: `void void x` — only the outer
12
+ // `void` is checked; the inner one is acceptable as the `void`
13
+ // operand of another `void`.
14
+ //
15
+ // This rule is AST-only — it does not consult the Checker for the
16
+ // surrounding function's return type, so `return void X` from a
17
+ // `void`-returning function is still reported. This matches the
18
+ // behavior the upstream rule produces with its
19
+ // `ignoreVoidReturningFunctions: false` default.
20
+ //
21
+ // https://typescript-eslint.io/rules/no-confusing-void-expression/
22
+ package linthost
23
+
24
+ import (
25
+ shimast "github.com/microsoft/typescript-go/shim/ast"
26
+ )
27
+
28
+ type noConfusingVoidExpression struct{}
29
+
30
+ func (noConfusingVoidExpression) Name() string {
31
+ return "typescript/no-confusing-void-expression"
32
+ }
33
+ func (noConfusingVoidExpression) Visits() []shimast.Kind {
34
+ return []shimast.Kind{shimast.KindVoidExpression}
35
+ }
36
+ func (noConfusingVoidExpression) Check(ctx *Context, node *shimast.Node) {
37
+ if isValidVoidExpressionPosition(node) {
38
+ return
39
+ }
40
+ ctx.Report(node, "Placing `void` operator in a value position is confusing — use it only as a statement, an arrow concise body, or inside another `void`.")
41
+ }
42
+
43
+ // isValidVoidExpressionPosition reports whether the `void X`
44
+ // expression at `node` sits in one of the three permitted positions.
45
+ // Parenthesized expressions are transparent — `(void x)` keeps the
46
+ // same effective context as `void x` for the surrounding code.
47
+ func isValidVoidExpressionPosition(node *shimast.Node) bool {
48
+ parent := node.Parent
49
+ for parent != nil && parent.Kind == shimast.KindParenthesizedExpression {
50
+ node = parent
51
+ parent = parent.Parent
52
+ }
53
+ if parent == nil {
54
+ return false
55
+ }
56
+ switch parent.Kind {
57
+ case shimast.KindExpressionStatement:
58
+ return true
59
+ case shimast.KindVoidExpression:
60
+ // `void void x` — the inner `void` is the operand of another
61
+ // `void`, which discards the result anyway.
62
+ return true
63
+ case shimast.KindArrowFunction:
64
+ arrow := parent.AsArrowFunction()
65
+ return arrow != nil && arrow.Body == node
66
+ }
67
+ return false
68
+ }
69
+
70
+ func init() {
71
+ Register(noConfusingVoidExpression{})
72
+ }