@ttsc/lint 0.13.1 → 0.14.0-dev.20260528.1

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
@@ -0,0 +1,178 @@
1
+ // typescript/no-unnecessary-template-expression: a backtick literal
2
+ // that carries no template-only behavior is just noise — a regular
3
+ // string literal renders the same characters with one fewer indirection.
4
+ // typescript-eslint:
5
+ // https://typescript-eslint.io/rules/no-unnecessary-template-expression/
6
+ //
7
+ // Type-aware. Three shapes collapse cleanly to a regular string literal:
8
+ //
9
+ // - A `NoSubstitutionTemplateLiteral` with no escaped backticks. The
10
+ // `\`` escape is what would force the template form once converted —
11
+ // a regular `"..."` does not need to escape a backtick, but the
12
+ // surrounding lint expects an exact source-preserving rewrite, so
13
+ // skip the literal when one is present.
14
+ // - A `TemplateExpression` whose head and the one span's tail text are
15
+ // both empty AND whose single span's expression is statically
16
+ // string-typed. `` `${name}` `` then coerces a known-string value
17
+ // through `String()` for no reason; just use `name`.
18
+ // - A `TemplateExpression` whose single span's expression is a
19
+ // `StringLiteral` or `NoSubstitutionTemplateLiteral` literal and
20
+ // whose head / tail text are empty — `` `${"abc"}` `` is the same
21
+ // as `"abc"`, independent of any Checker state.
22
+ //
23
+ // Tagged templates (`` tag`abc` ``, `` tag`${x}` ``) are excluded
24
+ // because the tag function reads the raw template payload and would
25
+ // observe a different shape if the literal were rewritten to a string.
26
+ package linthost
27
+
28
+ import (
29
+ "strings"
30
+
31
+ shimast "github.com/microsoft/typescript-go/shim/ast"
32
+ shimchecker "github.com/microsoft/typescript-go/shim/checker"
33
+ )
34
+
35
+ type noUnnecessaryTemplateExpression struct{}
36
+
37
+ func (noUnnecessaryTemplateExpression) Name() string {
38
+ return "typescript/no-unnecessary-template-expression"
39
+ }
40
+ func (noUnnecessaryTemplateExpression) NeedsTypeChecker() bool {
41
+ return true
42
+ }
43
+ func (noUnnecessaryTemplateExpression) Visits() []shimast.Kind {
44
+ return []shimast.Kind{
45
+ shimast.KindNoSubstitutionTemplateLiteral,
46
+ shimast.KindTemplateExpression,
47
+ }
48
+ }
49
+ func (noUnnecessaryTemplateExpression) Check(ctx *Context, node *shimast.Node) {
50
+ // Tag-function readers (`String.raw`, `dedent`, `gql`, `css`, …) see
51
+ // the raw template payload, so rewriting to a string literal would
52
+ // change observable behavior. Skip the entire literal in that case,
53
+ // matching `no-useless-escape`.
54
+ if isInsideTaggedTemplate(node) {
55
+ return
56
+ }
57
+ switch node.Kind {
58
+ case shimast.KindNoSubstitutionTemplateLiteral:
59
+ lit := node.AsNoSubstitutionTemplateLiteral()
60
+ if lit == nil {
61
+ return
62
+ }
63
+ // `RawText` is the verbatim payload between the backticks. The
64
+ // presence of `\`` means the source intentionally escapes a
65
+ // backtick that the template-literal form requires; leave such
66
+ // literals alone so the rewrite is always a pure source change.
67
+ if strings.Contains(lit.RawText, "\\`") {
68
+ return
69
+ }
70
+ ctx.Report(node, noUnnecessaryTemplateExpressionMessage)
71
+ case shimast.KindTemplateExpression:
72
+ expr := node.AsTemplateExpression()
73
+ if expr == nil || expr.TemplateSpans == nil {
74
+ return
75
+ }
76
+ spans := expr.TemplateSpans.Nodes
77
+ if len(spans) != 1 {
78
+ return
79
+ }
80
+ // Head text must be empty: `` `prefix${...}` `` has surrounding
81
+ // chars that are load-bearing and cannot collapse.
82
+ head := expr.Head
83
+ if head == nil || templateLiteralLikeText(head) != "" {
84
+ return
85
+ }
86
+ span := spans[0].AsTemplateSpan()
87
+ if span == nil || span.Expression == nil || span.Literal == nil {
88
+ return
89
+ }
90
+ // Tail text must be empty for the same reason as the head.
91
+ if templateLiteralLikeText(span.Literal) != "" {
92
+ return
93
+ }
94
+ inner := span.Expression
95
+ // A literal string operand collapses without consulting the
96
+ // Checker — `` `${"abc"}` `` is identical to `"abc"`.
97
+ if inner.Kind == shimast.KindStringLiteral ||
98
+ inner.Kind == shimast.KindNoSubstitutionTemplateLiteral {
99
+ ctx.Report(node, noUnnecessaryTemplateExpressionMessage)
100
+ return
101
+ }
102
+ if ctx.Checker == nil {
103
+ return
104
+ }
105
+ t := ctx.Checker.GetTypeAtLocation(inner)
106
+ if t == nil {
107
+ return
108
+ }
109
+ if isStringTypedForTemplateCollapse(t) {
110
+ ctx.Report(node, noUnnecessaryTemplateExpressionMessage)
111
+ }
112
+ }
113
+ }
114
+
115
+ const noUnnecessaryTemplateExpressionMessage = "Unnecessary template literal — replace the backtick form with a regular string literal."
116
+
117
+ // templateLiteralLikeText returns the parsed text payload of a
118
+ // TemplateHead / TemplateMiddle / TemplateTail / NoSubstitutionTemplate-
119
+ // Literal node. The same `Text` field lives on every shape via the
120
+ // shared `TemplateLiteralLikeNodeBase`, so we dispatch by kind.
121
+ func templateLiteralLikeText(node *shimast.Node) string {
122
+ if node == nil {
123
+ return ""
124
+ }
125
+ switch node.Kind {
126
+ case shimast.KindTemplateHead:
127
+ if h := node.AsTemplateHead(); h != nil {
128
+ return h.Text
129
+ }
130
+ case shimast.KindTemplateMiddle:
131
+ if m := node.AsTemplateMiddle(); m != nil {
132
+ return m.Text
133
+ }
134
+ case shimast.KindTemplateTail:
135
+ if tl := node.AsTemplateTail(); tl != nil {
136
+ return tl.Text
137
+ }
138
+ case shimast.KindNoSubstitutionTemplateLiteral:
139
+ if l := node.AsNoSubstitutionTemplateLiteral(); l != nil {
140
+ return l.Text
141
+ }
142
+ }
143
+ return ""
144
+ }
145
+
146
+ // isStringTypedForTemplateCollapse reports whether `t` is provably a
147
+ // string-like type whose interpolation in `` `${x}` `` is a no-op
148
+ // coercion. `any` / `unknown` / `never` are deliberately excluded so the
149
+ // rule does not light up on generic helpers — the upstream rule's
150
+ // `allowAny` semantics match this conservative choice. Union and
151
+ // intersection types collapse only when every constituent is itself
152
+ // string-like.
153
+ func isStringTypedForTemplateCollapse(t *shimchecker.Type) bool {
154
+ if t == nil {
155
+ return false
156
+ }
157
+ flags := t.Flags()
158
+ if flags&(shimchecker.TypeFlagsAny|shimchecker.TypeFlagsUnknown|shimchecker.TypeFlagsNever) != 0 {
159
+ return false
160
+ }
161
+ if flags&(shimchecker.TypeFlagsUnion|shimchecker.TypeFlagsIntersection) != 0 {
162
+ parts := t.Types()
163
+ if len(parts) == 0 {
164
+ return false
165
+ }
166
+ for _, part := range parts {
167
+ if !isStringTypedForTemplateCollapse(part) {
168
+ return false
169
+ }
170
+ }
171
+ return true
172
+ }
173
+ return flags&shimchecker.TypeFlagsStringLike != 0
174
+ }
175
+
176
+ func init() {
177
+ Register(noUnnecessaryTemplateExpression{})
178
+ }
@@ -0,0 +1,234 @@
1
+ // typescript/no-unnecessary-type-arguments: when a generic's explicit
2
+ // type argument matches the corresponding parameter's declared default,
3
+ // the argument is just restating the default. Dropping it leaves the
4
+ // identical type because TypeScript would substitute the default
5
+ // anyway. typescript-eslint:
6
+ // https://typescript-eslint.io/rules/no-unnecessary-type-arguments/
7
+ package linthost
8
+
9
+ import (
10
+ shimast "github.com/microsoft/typescript-go/shim/ast"
11
+ )
12
+
13
+ // noUnnecessaryTypeArguments visits the three syntactic positions that
14
+ // carry an explicit type-argument list — `Foo<T>` in type position,
15
+ // `new Foo<T>(…)`, and `foo<T>(…)` — and compares each argument against
16
+ // the parameter default declared on the generic. The check is type-aware
17
+ // because matching against the default requires resolving the generic's
18
+ // symbol back to its parameter list; the AST alone doesn't carry that
19
+ // link.
20
+ //
21
+ // The rule reports the rightmost run of arguments that equal their
22
+ // defaults: a trailing default-equal arg can be dropped without
23
+ // affecting the leftmost positional args. Once a non-equal arg appears
24
+ // scanning from the right, every argument to its left must stay
25
+ // explicit even when it equals its own default — TypeScript can only
26
+ // omit a contiguous suffix.
27
+ type noUnnecessaryTypeArguments struct{}
28
+
29
+ func (noUnnecessaryTypeArguments) Name() string {
30
+ return "typescript/no-unnecessary-type-arguments"
31
+ }
32
+ func (noUnnecessaryTypeArguments) NeedsTypeChecker() bool {
33
+ return true
34
+ }
35
+ func (noUnnecessaryTypeArguments) Visits() []shimast.Kind {
36
+ return []shimast.Kind{
37
+ shimast.KindTypeReference,
38
+ shimast.KindExpressionWithTypeArguments,
39
+ shimast.KindCallExpression,
40
+ shimast.KindNewExpression,
41
+ }
42
+ }
43
+ func (noUnnecessaryTypeArguments) Check(ctx *Context, node *shimast.Node) {
44
+ if ctx.Checker == nil {
45
+ return
46
+ }
47
+ args, nameNode := noUnnecessaryTypeArgumentsExtract(node)
48
+ if len(args) == 0 || nameNode == nil {
49
+ return
50
+ }
51
+ params := noUnnecessaryTypeArgumentsResolveParameters(ctx, nameNode)
52
+ if len(params) == 0 {
53
+ return
54
+ }
55
+ // Walk from the right: report contiguous trailing args that equal
56
+ // their declared defaults. Stop at the first mismatch — only the
57
+ // suffix is droppable.
58
+ for i := len(args) - 1; i >= 0; i-- {
59
+ if i >= len(params) {
60
+ continue
61
+ }
62
+ param := params[i]
63
+ if param == nil {
64
+ break
65
+ }
66
+ defaultNode := param.DefaultType
67
+ if defaultNode == nil {
68
+ break
69
+ }
70
+ argNode := args[i]
71
+ if argNode == nil {
72
+ break
73
+ }
74
+ argType := ctx.Checker.GetTypeFromTypeNode(argNode)
75
+ defaultType := ctx.Checker.GetTypeFromTypeNode(defaultNode)
76
+ if argType == nil || defaultType == nil {
77
+ break
78
+ }
79
+ if !ctx.Checker.IsTypeAssignableTo(argType, defaultType) {
80
+ break
81
+ }
82
+ if !ctx.Checker.IsTypeAssignableTo(defaultType, argType) {
83
+ break
84
+ }
85
+ ctx.Report(argNode, "This type argument equals the declared default — drop it.")
86
+ }
87
+ }
88
+
89
+ // noUnnecessaryTypeArgumentsExtract returns the explicit type-argument
90
+ // nodes and the identifier-or-property-access naming the generic the
91
+ // arguments apply to. Returns (nil, nil) when the node carries no
92
+ // explicit type arguments — the rule only fires on opt-in argument
93
+ // lists.
94
+ func noUnnecessaryTypeArgumentsExtract(node *shimast.Node) ([]*shimast.Node, *shimast.Node) {
95
+ switch node.Kind {
96
+ case shimast.KindTypeReference:
97
+ ref := node.AsTypeReferenceNode()
98
+ if ref == nil || ref.TypeArguments == nil {
99
+ return nil, nil
100
+ }
101
+ return ref.TypeArguments.Nodes, ref.TypeName
102
+ case shimast.KindExpressionWithTypeArguments:
103
+ ewta := node.AsExpressionWithTypeArguments()
104
+ if ewta == nil || ewta.TypeArguments == nil {
105
+ return nil, nil
106
+ }
107
+ return ewta.TypeArguments.Nodes, ewta.Expression
108
+ case shimast.KindCallExpression:
109
+ call := node.AsCallExpression()
110
+ if call == nil || call.TypeArguments == nil {
111
+ return nil, nil
112
+ }
113
+ return call.TypeArguments.Nodes, call.Expression
114
+ case shimast.KindNewExpression:
115
+ ne := node.AsNewExpression()
116
+ if ne == nil || ne.TypeArguments == nil {
117
+ return nil, nil
118
+ }
119
+ return ne.TypeArguments.Nodes, ne.Expression
120
+ }
121
+ return nil, nil
122
+ }
123
+
124
+ // noUnnecessaryTypeArgumentsResolveParameters resolves `nameNode` to a
125
+ // symbol and returns the type parameters declared on the first
126
+ // declaration that carries one. Returns nil when the symbol does not
127
+ // resolve or no declaration carries a type-parameter list — the rule
128
+ // then has nothing to compare against.
129
+ func noUnnecessaryTypeArgumentsResolveParameters(ctx *Context, nameNode *shimast.Node) []*shimast.TypeParameterDeclaration {
130
+ if nameNode == nil {
131
+ return nil
132
+ }
133
+ target := nameNode
134
+ // For property accesses (`a.b.Foo<T>`) the symbol-bearing identifier
135
+ // is the rightmost name, not the dotted root.
136
+ if target.Kind == shimast.KindPropertyAccessExpression {
137
+ access := target.AsPropertyAccessExpression()
138
+ if access == nil || access.Name() == nil {
139
+ return nil
140
+ }
141
+ target = access.Name()
142
+ } else if target.Kind == shimast.KindQualifiedName {
143
+ qn := target.AsQualifiedName()
144
+ if qn == nil || qn.Right == nil {
145
+ return nil
146
+ }
147
+ target = qn.Right
148
+ }
149
+ symbol := ctx.Checker.GetSymbolAtLocation(target)
150
+ if symbol == nil {
151
+ return nil
152
+ }
153
+ for _, decl := range symbol.Declarations {
154
+ if list := noUnnecessaryTypeArgumentsParamList(decl); list != nil {
155
+ return list
156
+ }
157
+ }
158
+ return nil
159
+ }
160
+
161
+ // noUnnecessaryTypeArgumentsParamList returns the type-parameter list on
162
+ // `decl` when the declaration kind carries one, or nil otherwise. The
163
+ // enumerated kinds match the host types TypeScript binds generic
164
+ // arguments against — function-shaped declarations, class / interface
165
+ // / alias declarations, and the method-like signatures that may appear
166
+ // inside them.
167
+ func noUnnecessaryTypeArgumentsParamList(decl *shimast.Node) []*shimast.TypeParameterDeclaration {
168
+ if decl == nil {
169
+ return nil
170
+ }
171
+ var list *shimast.TypeParameterList
172
+ switch decl.Kind {
173
+ case shimast.KindFunctionDeclaration:
174
+ if d := decl.AsFunctionDeclaration(); d != nil {
175
+ list = d.TypeParameters
176
+ }
177
+ case shimast.KindClassDeclaration:
178
+ if d := decl.AsClassDeclaration(); d != nil {
179
+ list = d.TypeParameters
180
+ }
181
+ case shimast.KindClassExpression:
182
+ if d := decl.AsClassExpression(); d != nil {
183
+ list = d.TypeParameters
184
+ }
185
+ case shimast.KindInterfaceDeclaration:
186
+ if d := decl.AsInterfaceDeclaration(); d != nil {
187
+ list = d.TypeParameters
188
+ }
189
+ case shimast.KindTypeAliasDeclaration:
190
+ if d := decl.AsTypeAliasDeclaration(); d != nil {
191
+ list = d.TypeParameters
192
+ }
193
+ case shimast.KindMethodDeclaration:
194
+ if d := decl.AsMethodDeclaration(); d != nil {
195
+ list = d.TypeParameters
196
+ }
197
+ case shimast.KindMethodSignature:
198
+ if d := decl.AsMethodSignatureDeclaration(); d != nil {
199
+ list = d.TypeParameters
200
+ }
201
+ case shimast.KindFunctionExpression:
202
+ if d := decl.AsFunctionExpression(); d != nil {
203
+ list = d.TypeParameters
204
+ }
205
+ case shimast.KindArrowFunction:
206
+ if d := decl.AsArrowFunction(); d != nil {
207
+ list = d.TypeParameters
208
+ }
209
+ case shimast.KindCallSignature:
210
+ if d := decl.AsCallSignatureDeclaration(); d != nil {
211
+ list = d.TypeParameters
212
+ }
213
+ case shimast.KindConstructSignature:
214
+ if d := decl.AsConstructSignatureDeclaration(); d != nil {
215
+ list = d.TypeParameters
216
+ }
217
+ }
218
+ if list == nil || len(list.Nodes) == 0 {
219
+ return nil
220
+ }
221
+ out := make([]*shimast.TypeParameterDeclaration, 0, len(list.Nodes))
222
+ for _, n := range list.Nodes {
223
+ if n == nil {
224
+ out = append(out, nil)
225
+ continue
226
+ }
227
+ out = append(out, n.AsTypeParameterDeclaration())
228
+ }
229
+ return out
230
+ }
231
+
232
+ func init() {
233
+ Register(noUnnecessaryTypeArguments{})
234
+ }
@@ -0,0 +1,157 @@
1
+ // typescript/no-unnecessary-type-assertion: `x as T`, `<T>x`, and `x!`
2
+ // add nothing when the static type of `x` already equals `T` (or is
3
+ // already non-nullable, for the `!` form). typescript-eslint
4
+ // recommended-type-checked:
5
+ // https://typescript-eslint.io/rules/no-unnecessary-type-assertion/
6
+ package linthost
7
+
8
+ import (
9
+ shimast "github.com/microsoft/typescript-go/shim/ast"
10
+ shimchecker "github.com/microsoft/typescript-go/shim/checker"
11
+ )
12
+
13
+ // noUnnecessaryTypeAssertion reports redundant `as`, type-prefix, and
14
+ // non-null assertions. Implementation notes:
15
+ //
16
+ // - Type-aware: requires the Checker so the source expression's static
17
+ // type can be compared against the asserted target. The shim
18
+ // re-exports the unexported `GetTypeFromTypeNode` and
19
+ // `IsTypeAssignableTo` methods directly, the same plumbing that the
20
+ // sibling `non-nullable-type-assertion-style` rule uses.
21
+ // - Symmetric assignability is used in place of literal type identity
22
+ // for the same reason as `non-nullable-type-assertion-style`: the
23
+ // Checker may widen literal types on one side and not the other
24
+ // (e.g. `"foo" as string` versus the literal `"foo"`), so requiring
25
+ // both directions of assignability stands in for structural
26
+ // equivalence without over-firing on widening.
27
+ // - The `as const` form is intentionally skipped because it produces
28
+ // a strictly narrower type than the source expression; `as const`
29
+ // assertions on already-literal expressions are handled by the
30
+ // companion `typescript/prefer-as-const` rule.
31
+ // - For `x!` (NonNullExpression) the rule fires when the inner
32
+ // expression's static type has no `null` or `undefined`
33
+ // constituent — the `!` strips nothing.
34
+ type noUnnecessaryTypeAssertion struct{}
35
+
36
+ func (noUnnecessaryTypeAssertion) Name() string {
37
+ return "typescript/no-unnecessary-type-assertion"
38
+ }
39
+ func (noUnnecessaryTypeAssertion) NeedsTypeChecker() bool {
40
+ return true
41
+ }
42
+ func (noUnnecessaryTypeAssertion) Visits() []shimast.Kind {
43
+ return []shimast.Kind{
44
+ shimast.KindAsExpression,
45
+ shimast.KindTypeAssertionExpression,
46
+ shimast.KindNonNullExpression,
47
+ }
48
+ }
49
+ func (noUnnecessaryTypeAssertion) Check(ctx *Context, node *shimast.Node) {
50
+ if ctx.Checker == nil {
51
+ return
52
+ }
53
+ switch node.Kind {
54
+ case shimast.KindAsExpression:
55
+ as := node.AsAsExpression()
56
+ if as == nil || as.Expression == nil || as.Type == nil {
57
+ return
58
+ }
59
+ if isConstTypeReference(as.Type) {
60
+ return
61
+ }
62
+ noUnnecessaryTypeAssertionCheckAssertion(ctx, node, as.Expression, as.Type)
63
+ case shimast.KindTypeAssertionExpression:
64
+ ta := node.AsTypeAssertion()
65
+ if ta == nil || ta.Expression == nil || ta.Type == nil {
66
+ return
67
+ }
68
+ if isConstTypeReference(ta.Type) {
69
+ return
70
+ }
71
+ noUnnecessaryTypeAssertionCheckAssertion(ctx, node, ta.Expression, ta.Type)
72
+ case shimast.KindNonNullExpression:
73
+ nn := node.AsNonNullExpression()
74
+ if nn == nil || nn.Expression == nil {
75
+ return
76
+ }
77
+ sourceType := ctx.Checker.GetTypeAtLocation(nn.Expression)
78
+ if sourceType == nil {
79
+ return
80
+ }
81
+ if noUnnecessaryTypeAssertionIsNullable(sourceType) {
82
+ return
83
+ }
84
+ ctx.Report(node, "This assertion is unnecessary since it does not change the type of the expression.")
85
+ }
86
+ }
87
+
88
+ // noUnnecessaryTypeAssertionCheckAssertion runs the shared logic for
89
+ // `expr as T` and `<T>expr`: report when the asserted type and source
90
+ // type are mutually assignable.
91
+ func noUnnecessaryTypeAssertionCheckAssertion(ctx *Context, node, expr, typeNode *shimast.Node) {
92
+ sourceType := ctx.Checker.GetTypeAtLocation(expr)
93
+ if sourceType == nil {
94
+ return
95
+ }
96
+ assertedType := ctx.Checker.GetTypeFromTypeNode(typeNode)
97
+ if assertedType == nil {
98
+ return
99
+ }
100
+ // Bidirectional assignability stands in for type identity: see the
101
+ // note on `non-nullable-type-assertion-style`. The assertion is
102
+ // redundant only when both sides describe the same set of values.
103
+ if !ctx.Checker.IsTypeAssignableTo(sourceType, assertedType) {
104
+ return
105
+ }
106
+ if !ctx.Checker.IsTypeAssignableTo(assertedType, sourceType) {
107
+ return
108
+ }
109
+ ctx.Report(node, "This assertion is unnecessary since it does not change the type of the expression.")
110
+ }
111
+
112
+ // isConstTypeReference reports whether the type node is the bare
113
+ // identifier `const`, i.e. the `as const` syntax. The TypeScript parser
114
+ // represents `as const` as an AsExpression / TypeAssertion whose type
115
+ // node is a TypeReference to the identifier `const` rather than a real
116
+ // type — every other rule that touches assertion nodes needs to skip
117
+ // it because it is structurally an assertion but semantically a const
118
+ // context request.
119
+ func isConstTypeReference(typeNode *shimast.Node) bool {
120
+ if typeNode == nil || typeNode.Kind != shimast.KindTypeReference {
121
+ return false
122
+ }
123
+ ref := typeNode.AsTypeReferenceNode()
124
+ if ref == nil {
125
+ return false
126
+ }
127
+ return identifierText(ref.TypeName) == "const"
128
+ }
129
+
130
+ // noUnnecessaryTypeAssertionIsNullable reports whether t carries `null`
131
+ // or `undefined` at the top level or inside a union constituent. The
132
+ // shape mirrors `nonNullableTypeAssertionStyleIsNullable` because both
133
+ // rules answer the same question about the source expression.
134
+ func noUnnecessaryTypeAssertionIsNullable(t *shimchecker.Type) bool {
135
+ if t == nil {
136
+ return false
137
+ }
138
+ flags := t.Flags()
139
+ if flags&(shimchecker.TypeFlagsNull|shimchecker.TypeFlagsUndefined) != 0 {
140
+ return true
141
+ }
142
+ if flags&shimchecker.TypeFlagsUnion != 0 {
143
+ for _, part := range t.Types() {
144
+ if part == nil {
145
+ continue
146
+ }
147
+ if noUnnecessaryTypeAssertionIsNullable(part) {
148
+ return true
149
+ }
150
+ }
151
+ }
152
+ return false
153
+ }
154
+
155
+ func init() {
156
+ Register(noUnnecessaryTypeAssertion{})
157
+ }
@@ -0,0 +1,82 @@
1
+ // typescript/no-unsafe-argument: passing an `any`-typed value into a
2
+ // concretely typed parameter discards every static check the function's
3
+ // signature would otherwise enforce. The call still runs, but the value
4
+ // flows in unchecked and downstream uses operate on whatever the
5
+ // runtime actually supplies. typescript-eslint:
6
+ // https://typescript-eslint.io/rules/no-unsafe-argument/
7
+ //
8
+ // Type-aware. The rule visits `CallExpression` and `NewExpression` and
9
+ // reports each argument whose static type carries `TypeFlagsAny` when
10
+ // the callee's resolved type is itself a concrete (non-`any`) callable.
11
+ // `unknown` is intentionally NOT flagged: it forces a narrowing
12
+ // assertion before the call, which is the explicit ergonomic the
13
+ // upstream rule pushes toward.
14
+ package linthost
15
+
16
+ import (
17
+ shimast "github.com/microsoft/typescript-go/shim/ast"
18
+ )
19
+
20
+ type noUnsafeArgument struct{}
21
+
22
+ func (noUnsafeArgument) Name() string { return "typescript/no-unsafe-argument" }
23
+ func (noUnsafeArgument) NeedsTypeChecker() bool {
24
+ return true
25
+ }
26
+ func (noUnsafeArgument) Visits() []shimast.Kind {
27
+ return []shimast.Kind{
28
+ shimast.KindCallExpression,
29
+ shimast.KindNewExpression,
30
+ }
31
+ }
32
+ func (noUnsafeArgument) Check(ctx *Context, node *shimast.Node) {
33
+ if ctx.Checker == nil {
34
+ return
35
+ }
36
+ var callee *shimast.Node
37
+ var args []*shimast.Node
38
+ switch node.Kind {
39
+ case shimast.KindCallExpression:
40
+ if call := node.AsCallExpression(); call != nil {
41
+ callee = call.Expression
42
+ if call.Arguments != nil {
43
+ args = call.Arguments.Nodes
44
+ }
45
+ }
46
+ case shimast.KindNewExpression:
47
+ if ne := node.AsNewExpression(); ne != nil {
48
+ callee = ne.Expression
49
+ if ne.Arguments != nil {
50
+ args = ne.Arguments.Nodes
51
+ }
52
+ }
53
+ }
54
+ if callee == nil || len(args) == 0 {
55
+ return
56
+ }
57
+ calleeType := ctx.Checker.GetTypeAtLocation(callee)
58
+ if calleeType == nil || typeIsUnsafeAny(calleeType) {
59
+ // Callee itself is `any` — no-unsafe-call handles that.
60
+ return
61
+ }
62
+ for _, arg := range args {
63
+ if arg == nil {
64
+ continue
65
+ }
66
+ stripped := stripParens(arg)
67
+ if stripped == nil {
68
+ continue
69
+ }
70
+ argType := ctx.Checker.GetTypeAtLocation(stripped)
71
+ if !typeIsUnsafeAny(argType) {
72
+ continue
73
+ }
74
+ ctx.Report(arg, noUnsafeArgumentMessage)
75
+ }
76
+ }
77
+
78
+ const noUnsafeArgumentMessage = "Unsafe passing of a value typed as `any` into a typed parameter. Narrow the value before forwarding it."
79
+
80
+ func init() {
81
+ Register(noUnsafeArgument{})
82
+ }