@ttsc/lint 0.13.0 → 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 (467) 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 +60 -37
  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/compile.go +33 -2
  116. package/linthost/config.go +48 -17
  117. package/linthost/config_format.go +9 -9
  118. package/linthost/directives.go +67 -25
  119. package/linthost/dispatch.go +14 -3
  120. package/linthost/engine.go +160 -40
  121. package/linthost/fix.go +2 -2
  122. package/linthost/flags_gen.go +17 -15
  123. package/linthost/host.go +40 -3
  124. package/linthost/lsp.go +747 -0
  125. package/linthost/print_dispatch.go +2 -2
  126. package/linthost/print_nodes_function.go +2 -2
  127. package/linthost/print_nodes_object.go +1 -1
  128. package/linthost/rule_names.go +14 -0
  129. package/linthost/rules_arrays.go +2 -2
  130. package/linthost/rules_boundaries.go +532 -0
  131. package/linthost/rules_camelcase.go +133 -0
  132. package/linthost/rules_complexity.go +94 -0
  133. package/linthost/rules_consistent_return.go +130 -0
  134. package/linthost/rules_console.go +1 -1
  135. package/linthost/rules_core_extra.go +739 -0
  136. package/linthost/rules_curly.go +70 -0
  137. package/linthost/rules_cypress.go +608 -0
  138. package/linthost/rules_debugger.go +2 -2
  139. package/linthost/rules_default_case.go +39 -0
  140. package/linthost/rules_default_case_last.go +46 -0
  141. package/linthost/rules_dupes.go +3 -3
  142. package/linthost/rules_empty.go +3 -3
  143. package/linthost/rules_escape.go +44 -24
  144. package/linthost/rules_eval.go +2 -2
  145. package/linthost/rules_finally.go +2 -2
  146. package/linthost/rules_format_jsdoc.go +1 -1
  147. package/linthost/rules_format_print_width.go +9 -9
  148. package/linthost/rules_format_quotes.go +1 -1
  149. package/linthost/rules_format_semi.go +1 -1
  150. package/linthost/rules_format_sort_imports.go +1 -1
  151. package/linthost/rules_format_trailing_comma.go +1 -1
  152. package/linthost/rules_functional.go +967 -0
  153. package/linthost/rules_gap.go +24 -45
  154. package/linthost/rules_grouped_accessor_pairs.go +87 -0
  155. package/linthost/rules_guard_for_in.go +198 -0
  156. package/linthost/rules_id_length.go +77 -0
  157. package/linthost/rules_imports.go +70 -2
  158. package/linthost/rules_init_declarations.go +53 -0
  159. package/linthost/rules_jest.go +618 -0
  160. package/linthost/rules_jsdoc.go +502 -0
  161. package/linthost/rules_jsx_a11y.go +1264 -0
  162. package/linthost/rules_logic.go +12 -12
  163. package/linthost/rules_loops.go +1 -1
  164. package/linthost/rules_max_classes_per_file.go +58 -0
  165. package/linthost/rules_max_depth.go +83 -0
  166. package/linthost/rules_max_lines.go +101 -0
  167. package/linthost/rules_max_lines_per_function.go +57 -0
  168. package/linthost/rules_max_nested_callbacks.go +61 -0
  169. package/linthost/rules_max_params.go +49 -0
  170. package/linthost/rules_max_statements.go +59 -0
  171. package/linthost/rules_misc.go +1 -1
  172. package/linthost/rules_nextjs.go +697 -0
  173. package/linthost/rules_no_else_return.go +75 -0
  174. package/linthost/rules_no_empty_named_blocks.go +91 -0
  175. package/linthost/rules_no_extend_native.go +51 -0
  176. package/linthost/rules_no_import_assign.go +140 -0
  177. package/linthost/rules_no_invalid_this.go +52 -0
  178. package/linthost/rules_no_loop_func.go +85 -0
  179. package/linthost/rules_no_magic_numbers.go +123 -0
  180. package/linthost/rules_no_mixed_operators.go +80 -0
  181. package/linthost/rules_no_param_reassign.go +98 -0
  182. package/linthost/rules_no_redeclare.go +270 -0
  183. package/linthost/rules_no_restricted_imports.go +105 -0
  184. package/linthost/rules_no_restricted_syntax.go +49 -0
  185. package/linthost/rules_no_shadow.go +147 -0
  186. package/linthost/rules_no_unreachable.go +77 -0
  187. package/linthost/rules_no_useless_assignment.go +120 -0
  188. package/linthost/rules_no_useless_constructor.go +245 -0
  189. package/linthost/rules_no_useless_return.go +51 -0
  190. package/linthost/rules_params.go +1 -1
  191. package/linthost/rules_playwright.go +788 -0
  192. package/linthost/rules_prefer_arrow_callback.go +124 -0
  193. package/linthost/rules_prefer_destructuring.go +98 -0
  194. package/linthost/rules_prefer_named_capture_group.go +129 -0
  195. package/linthost/rules_prefer_rest_params.go +94 -0
  196. package/linthost/rules_problems.go +41 -30
  197. package/linthost/rules_promise.go +1128 -73
  198. package/linthost/rules_protos.go +2 -2
  199. package/linthost/rules_react.go +773 -0
  200. package/linthost/rules_react_extras.go +227 -0
  201. package/linthost/rules_react_hooks.go +848 -0
  202. package/linthost/rules_react_perf.go +293 -0
  203. package/linthost/rules_react_refresh.go +583 -0
  204. package/linthost/rules_regexp.go +410 -0
  205. package/linthost/rules_security.go +830 -0
  206. package/linthost/rules_self.go +2 -2
  207. package/linthost/rules_solid.go +1073 -0
  208. package/linthost/rules_sort_imports.go +69 -0
  209. package/linthost/rules_sort_keys.go +134 -0
  210. package/linthost/rules_storybook.go +1176 -0
  211. package/linthost/rules_strings.go +4 -4
  212. package/linthost/rules_suggestions.go +38 -38
  213. package/linthost/rules_tanstack_query.go +844 -0
  214. package/linthost/rules_testing_library.go +1204 -0
  215. package/linthost/rules_throw.go +1 -1
  216. package/linthost/rules_ts.go +19 -19
  217. package/linthost/rules_ts_async.go +399 -0
  218. package/linthost/rules_ts_class_literal_property_style.go +115 -0
  219. package/linthost/rules_ts_consistent_type_exports.go +256 -0
  220. package/linthost/rules_ts_explicit_function_return_type.go +67 -0
  221. package/linthost/rules_ts_extra.go +155 -36
  222. package/linthost/rules_ts_no_base_to_string.go +218 -0
  223. package/linthost/rules_ts_no_confusing_void.go +72 -0
  224. package/linthost/rules_ts_no_deprecated.go +195 -0
  225. package/linthost/rules_ts_no_for_in_array.go +84 -0
  226. package/linthost/rules_ts_no_magic_numbers.go +124 -0
  227. package/linthost/rules_ts_no_meaningless_void_operator.go +84 -0
  228. package/linthost/rules_ts_no_misused_spread.go +104 -0
  229. package/linthost/rules_ts_no_redundant_type_constituents.go +113 -0
  230. package/linthost/rules_ts_no_restricted_types.go +62 -0
  231. package/linthost/rules_ts_no_unnecessary_boolean_literal_compare.go +129 -0
  232. package/linthost/rules_ts_no_unnecessary_condition.go +250 -0
  233. package/linthost/rules_ts_no_unnecessary_qualifier.go +118 -0
  234. package/linthost/rules_ts_no_unnecessary_template_expression.go +178 -0
  235. package/linthost/rules_ts_no_unnecessary_type_arguments.go +234 -0
  236. package/linthost/rules_ts_no_unnecessary_type_assertion.go +157 -0
  237. package/linthost/rules_ts_no_unsafe_argument.go +82 -0
  238. package/linthost/rules_ts_no_unsafe_assignment.go +102 -0
  239. package/linthost/rules_ts_no_unsafe_call.go +82 -0
  240. package/linthost/rules_ts_no_unsafe_enum_comparison.go +235 -0
  241. package/linthost/rules_ts_no_unsafe_member_access.go +58 -0
  242. package/linthost/rules_ts_no_unsafe_return.go +126 -0
  243. package/linthost/rules_ts_no_unsafe_unary_minus.go +81 -0
  244. package/linthost/rules_ts_no_useless_constructor.go +52 -0
  245. package/linthost/rules_ts_non_nullable_type_assertion_style.go +108 -0
  246. package/linthost/rules_ts_parameter_properties.go +38 -0
  247. package/linthost/rules_ts_prefer_find.go +178 -0
  248. package/linthost/rules_ts_prefer_includes.go +255 -0
  249. package/linthost/rules_ts_prefer_nullish_coalescing.go +104 -0
  250. package/linthost/rules_ts_prefer_optional_chain.go +228 -0
  251. package/linthost/rules_ts_prefer_promise_reject_errors.go +176 -0
  252. package/linthost/rules_ts_prefer_readonly.go +73 -0
  253. package/linthost/rules_ts_prefer_reduce_type_parameter.go +116 -0
  254. package/linthost/rules_ts_prefer_regexp_exec.go +122 -0
  255. package/linthost/rules_ts_prefer_return_this_type.go +135 -0
  256. package/linthost/rules_ts_prefer_string_starts_ends_with.go +360 -0
  257. package/linthost/rules_ts_promise_function_async.go +77 -0
  258. package/linthost/rules_ts_related_getter_setter_pairs.go +113 -0
  259. package/linthost/rules_ts_require_array_sort_compare.go +96 -0
  260. package/linthost/rules_ts_restrict_plus_operands.go +127 -0
  261. package/linthost/rules_ts_restrict_template_expressions.go +95 -0
  262. package/linthost/rules_ts_simple.go +387 -0
  263. package/linthost/rules_ts_sort_type_constituents.go +144 -0
  264. package/linthost/rules_ts_strict_boolean_expressions.go +157 -0
  265. package/linthost/rules_ts_switch_exhaustiveness_check.go +147 -0
  266. package/linthost/rules_ts_unbound_method.go +126 -0
  267. package/linthost/rules_tsdoc.go +136 -0
  268. package/linthost/rules_unicorn_better_regex.go +27 -0
  269. package/linthost/rules_unicorn_catch_error_name.go +46 -0
  270. package/linthost/rules_unicorn_consistent_assert.go +47 -0
  271. package/linthost/rules_unicorn_consistent_date_clone.go +54 -0
  272. package/linthost/rules_unicorn_consistent_destructuring.go +25 -0
  273. package/linthost/rules_unicorn_consistent_empty_array_spread.go +62 -0
  274. package/linthost/rules_unicorn_consistent_existence_index_check.go +80 -0
  275. package/linthost/rules_unicorn_consistent_function_scoping.go +25 -0
  276. package/linthost/rules_unicorn_consistent_template_literal_escape.go +25 -0
  277. package/linthost/rules_unicorn_custom_error_definition.go +138 -0
  278. package/linthost/rules_unicorn_empty_brace_spaces.go +73 -0
  279. package/linthost/rules_unicorn_error_message.go +64 -0
  280. package/linthost/rules_unicorn_escape_case.go +51 -0
  281. package/linthost/rules_unicorn_expiring_todo_comments.go +78 -0
  282. package/linthost/rules_unicorn_explicit_length_check.go +88 -0
  283. package/linthost/rules_unicorn_filename_case.go +29 -0
  284. package/linthost/rules_unicorn_import_style.go +28 -0
  285. package/linthost/rules_unicorn_isolated_functions.go +29 -0
  286. package/linthost/rules_unicorn_new_for_builtins.go +87 -0
  287. package/linthost/rules_unicorn_no_abusive_eslint_disable.go +63 -0
  288. package/linthost/rules_unicorn_no_accessor_recursion.go +115 -0
  289. package/linthost/rules_unicorn_no_anonymous_default_export.go +74 -0
  290. package/linthost/rules_unicorn_no_array_callback_reference.go +65 -0
  291. package/linthost/rules_unicorn_no_array_for_each.go +40 -0
  292. package/linthost/rules_unicorn_no_array_method_this_argument.go +61 -0
  293. package/linthost/rules_unicorn_no_array_reduce.go +41 -0
  294. package/linthost/rules_unicorn_no_array_reverse.go +44 -0
  295. package/linthost/rules_unicorn_no_array_sort.go +43 -0
  296. package/linthost/rules_unicorn_no_await_expression_member.go +40 -0
  297. package/linthost/rules_unicorn_no_await_in_promise_methods.go +69 -0
  298. package/linthost/rules_unicorn_no_console_spaces.go +61 -0
  299. package/linthost/rules_unicorn_no_document_cookie.go +41 -0
  300. package/linthost/rules_unicorn_no_empty_file.go +44 -0
  301. package/linthost/rules_unicorn_no_for_loop.go +102 -0
  302. package/linthost/rules_unicorn_no_hex_escape.go +42 -0
  303. package/linthost/rules_unicorn_no_immediate_mutation.go +90 -0
  304. package/linthost/rules_unicorn_no_instanceof_builtins.go +66 -0
  305. package/linthost/rules_unicorn_no_invalid_fetch_options.go +79 -0
  306. package/linthost/rules_unicorn_no_invalid_remove_event_listener.go +51 -0
  307. package/linthost/rules_unicorn_no_keyword_prefix.go +101 -0
  308. package/linthost/rules_unicorn_no_lonely_if.go +44 -0
  309. package/linthost/rules_unicorn_no_magic_array_flat_depth.go +51 -0
  310. package/linthost/rules_unicorn_no_named_default.go +54 -0
  311. package/linthost/rules_unicorn_no_negated_condition.go +85 -0
  312. package/linthost/rules_unicorn_no_negation_in_equality_check.go +50 -0
  313. package/linthost/rules_unicorn_no_nested_ternary.go +43 -0
  314. package/linthost/rules_unicorn_no_new_array.go +30 -0
  315. package/linthost/rules_unicorn_no_new_buffer.go +31 -0
  316. package/linthost/rules_unicorn_no_null.go +24 -0
  317. package/linthost/rules_unicorn_no_object_as_default_parameter.go +48 -0
  318. package/linthost/rules_unicorn_no_process_exit.go +43 -0
  319. package/linthost/rules_unicorn_no_single_promise_in_promise_methods.go +59 -0
  320. package/linthost/rules_unicorn_no_static_only_class.go +56 -0
  321. package/linthost/rules_unicorn_no_thenable.go +74 -0
  322. package/linthost/rules_unicorn_no_this_assignment.go +35 -0
  323. package/linthost/rules_unicorn_no_typeof_undefined.go +58 -0
  324. package/linthost/rules_unicorn_no_unnecessary_array_flat_depth.go +49 -0
  325. package/linthost/rules_unicorn_no_unnecessary_array_splice_count.go +70 -0
  326. package/linthost/rules_unicorn_no_unnecessary_await.go +51 -0
  327. package/linthost/rules_unicorn_no_unnecessary_polyfills.go +32 -0
  328. package/linthost/rules_unicorn_no_unnecessary_slice_end.go +48 -0
  329. package/linthost/rules_unicorn_no_unreadable_array_destructuring.go +115 -0
  330. package/linthost/rules_unicorn_no_unreadable_iife.go +50 -0
  331. package/linthost/rules_unicorn_no_unused_properties.go +30 -0
  332. package/linthost/rules_unicorn_no_useless_collection_argument.go +63 -0
  333. package/linthost/rules_unicorn_no_useless_error_capture_stack_trace.go +46 -0
  334. package/linthost/rules_unicorn_no_useless_fallback_in_spread.go +81 -0
  335. package/linthost/rules_unicorn_no_useless_iterator_to_array.go +72 -0
  336. package/linthost/rules_unicorn_no_useless_length_check.go +144 -0
  337. package/linthost/rules_unicorn_no_useless_promise_resolve_reject.go +81 -0
  338. package/linthost/rules_unicorn_no_useless_spread.go +67 -0
  339. package/linthost/rules_unicorn_no_useless_switch_case.go +55 -0
  340. package/linthost/rules_unicorn_no_useless_undefined.go +55 -0
  341. package/linthost/rules_unicorn_no_zero_fractions.go +52 -0
  342. package/linthost/rules_unicorn_number_literal_case.go +69 -0
  343. package/linthost/rules_unicorn_numeric_separators_style.go +75 -0
  344. package/linthost/rules_unicorn_prefer_add_event_listener.go +66 -0
  345. package/linthost/rules_unicorn_prefer_array_find.go +51 -0
  346. package/linthost/rules_unicorn_prefer_array_flat.go +52 -0
  347. package/linthost/rules_unicorn_prefer_array_flat_map.go +63 -0
  348. package/linthost/rules_unicorn_prefer_array_index_of.go +147 -0
  349. package/linthost/rules_unicorn_prefer_array_some.go +67 -0
  350. package/linthost/rules_unicorn_prefer_at.go +77 -0
  351. package/linthost/rules_unicorn_prefer_bigint_literals.go +77 -0
  352. package/linthost/rules_unicorn_prefer_blob_reading_methods.go +44 -0
  353. package/linthost/rules_unicorn_prefer_class_fields.go +93 -0
  354. package/linthost/rules_unicorn_prefer_classlist_toggle.go +120 -0
  355. package/linthost/rules_unicorn_prefer_code_point.go +49 -0
  356. package/linthost/rules_unicorn_prefer_date_now.go +78 -0
  357. package/linthost/rules_unicorn_prefer_default_parameters.go +144 -0
  358. package/linthost/rules_unicorn_prefer_dom_node_append.go +40 -0
  359. package/linthost/rules_unicorn_prefer_dom_node_dataset.go +55 -0
  360. package/linthost/rules_unicorn_prefer_dom_node_remove.go +41 -0
  361. package/linthost/rules_unicorn_prefer_dom_node_text_content.go +37 -0
  362. package/linthost/rules_unicorn_prefer_event_target.go +36 -0
  363. package/linthost/rules_unicorn_prefer_export_from.go +129 -0
  364. package/linthost/rules_unicorn_prefer_global_this.go +127 -0
  365. package/linthost/rules_unicorn_prefer_import_meta_properties.go +66 -0
  366. package/linthost/rules_unicorn_prefer_includes.go +149 -0
  367. package/linthost/rules_unicorn_prefer_json_parse_buffer.go +65 -0
  368. package/linthost/rules_unicorn_prefer_keyboard_event_key.go +38 -0
  369. package/linthost/rules_unicorn_prefer_logical_operator_over_ternary.go +48 -0
  370. package/linthost/rules_unicorn_prefer_math_min_max.go +60 -0
  371. package/linthost/rules_unicorn_prefer_math_trunc.go +62 -0
  372. package/linthost/rules_unicorn_prefer_modern_dom_apis.go +47 -0
  373. package/linthost/rules_unicorn_prefer_modern_math_apis.go +70 -0
  374. package/linthost/rules_unicorn_prefer_module.go +50 -0
  375. package/linthost/rules_unicorn_prefer_native_coercion_functions.go +114 -0
  376. package/linthost/rules_unicorn_prefer_negative_index.go +74 -0
  377. package/linthost/rules_unicorn_prefer_node_protocol.go +122 -0
  378. package/linthost/rules_unicorn_prefer_number_properties.go +88 -0
  379. package/linthost/rules_unicorn_prefer_object_from_entries.go +55 -0
  380. package/linthost/rules_unicorn_prefer_optional_catch_binding.go +62 -0
  381. package/linthost/rules_unicorn_prefer_prototype_methods.go +54 -0
  382. package/linthost/rules_unicorn_prefer_query_selector.go +56 -0
  383. package/linthost/rules_unicorn_prefer_reflect_apply.go +36 -0
  384. package/linthost/rules_unicorn_prefer_regexp_test_rule.go +80 -0
  385. package/linthost/rules_unicorn_prefer_response_static_json.go +53 -0
  386. package/linthost/rules_unicorn_prefer_set_has.go +42 -0
  387. package/linthost/rules_unicorn_prefer_set_size.go +48 -0
  388. package/linthost/rules_unicorn_prefer_simple_condition_first.go +34 -0
  389. package/linthost/rules_unicorn_prefer_single_call.go +96 -0
  390. package/linthost/rules_unicorn_prefer_spread.go +51 -0
  391. package/linthost/rules_unicorn_prefer_string_raw.go +43 -0
  392. package/linthost/rules_unicorn_prefer_string_replace_all.go +95 -0
  393. package/linthost/rules_unicorn_prefer_string_slice.go +43 -0
  394. package/linthost/rules_unicorn_prefer_string_starts_ends_with.go +148 -0
  395. package/linthost/rules_unicorn_prefer_string_trim_start_end.go +48 -0
  396. package/linthost/rules_unicorn_prefer_structured_clone.go +71 -0
  397. package/linthost/rules_unicorn_prefer_switch.go +103 -0
  398. package/linthost/rules_unicorn_prefer_ternary.go +71 -0
  399. package/linthost/rules_unicorn_prefer_top_level_await.go +72 -0
  400. package/linthost/rules_unicorn_prefer_type_error.go +127 -0
  401. package/linthost/rules_unicorn_prevent_abbreviations.go +127 -0
  402. package/linthost/rules_unicorn_relative_url_style.go +49 -0
  403. package/linthost/rules_unicorn_require_array_join_separator.go +45 -0
  404. package/linthost/rules_unicorn_require_module_attributes.go +54 -0
  405. package/linthost/rules_unicorn_require_module_specifiers.go +55 -0
  406. package/linthost/rules_unicorn_require_number_to_fixed_digits_argument.go +43 -0
  407. package/linthost/rules_unicorn_require_post_message_target_origin.go +44 -0
  408. package/linthost/rules_unicorn_string_content.go +27 -0
  409. package/linthost/rules_unicorn_switch_case_braces.go +42 -0
  410. package/linthost/rules_unicorn_switch_case_break_position.go +31 -0
  411. package/linthost/rules_unicorn_template_indent.go +28 -0
  412. package/linthost/rules_unicorn_text_encoding_identifier_case.go +72 -0
  413. package/linthost/rules_unicorn_throw_new_error.go +61 -0
  414. package/linthost/rules_var.go +10 -4
  415. package/linthost/rules_vitest.go +568 -0
  416. package/package.json +3 -3
  417. package/plugin/main.go +49 -3
  418. package/rule/astutil/astutil.go +10 -3
  419. package/rule/rule.go +12 -10
  420. package/src/defaultFormat.ts +11 -8
  421. package/src/index.ts +65 -43
  422. package/src/structures/ITtscLintConfig.ts +12 -6
  423. package/src/structures/{ITtscLintFormatConfig.ts → ITtscLintFormat.ts} +2 -2
  424. package/src/structures/TtscLintRuleSetting.ts +55 -0
  425. package/src/structures/index.ts +3 -4
  426. package/src/structures/rules/ITtscLintBoundariesRuleOptions.ts +128 -0
  427. package/src/structures/rules/ITtscLintBoundariesRules.ts +95 -0
  428. package/src/structures/rules/ITtscLintContributorRules.ts +21 -0
  429. package/src/structures/rules/ITtscLintCoreRules.ts +1406 -0
  430. package/src/structures/rules/ITtscLintCypressRuleOptions.ts +18 -0
  431. package/src/structures/rules/ITtscLintCypressRules.ts +145 -0
  432. package/src/structures/rules/ITtscLintFunctionalRuleOptions.ts +213 -0
  433. package/src/structures/rules/ITtscLintFunctionalRules.ts +202 -0
  434. package/src/structures/rules/ITtscLintJestRules.ts +220 -0
  435. package/src/structures/rules/ITtscLintJsdocRules.ts +153 -0
  436. package/src/structures/rules/ITtscLintJsxA11yRules.ts +339 -0
  437. package/src/structures/rules/ITtscLintNextjsRules.ts +206 -0
  438. package/src/structures/rules/ITtscLintPlaywrightRules.ts +361 -0
  439. package/src/structures/rules/ITtscLintPromiseRules.ts +205 -0
  440. package/src/structures/rules/ITtscLintReactPerfRuleOptions.ts +19 -0
  441. package/src/structures/rules/ITtscLintReactPerfRules.ts +55 -0
  442. package/src/structures/rules/ITtscLintReactRuleOptions.ts +43 -0
  443. package/src/structures/rules/ITtscLintReactRules.ts +321 -0
  444. package/src/structures/rules/ITtscLintRegexpRules.ts +212 -0
  445. package/src/structures/rules/ITtscLintRuleOptionsMap.ts +89 -0
  446. package/src/structures/rules/ITtscLintRules.ts +77 -0
  447. package/src/structures/rules/ITtscLintSecurityRules.ts +162 -0
  448. package/src/structures/rules/ITtscLintSolidRules.ts +202 -0
  449. package/src/structures/rules/ITtscLintStorybookRuleOptions.ts +23 -0
  450. package/src/structures/rules/ITtscLintStorybookRules.ts +193 -0
  451. package/src/structures/rules/ITtscLintTanstackQueryRules.ts +102 -0
  452. package/src/structures/rules/ITtscLintTestingLibraryRuleOptions.ts +24 -0
  453. package/src/structures/rules/ITtscLintTestingLibraryRules.ts +342 -0
  454. package/src/structures/rules/ITtscLintTypeScriptRules.ts +1230 -0
  455. package/src/structures/rules/ITtscLintUnicornRules.ts +1143 -0
  456. package/src/structures/rules/ITtscLintVitestRules.ts +154 -0
  457. package/src/structures/rules/index.ts +31 -0
  458. package/lib/structures/ITtscLintFormatConfig.js.map +0 -1
  459. package/lib/structures/TtscLintRule.d.ts +0 -17
  460. package/lib/structures/TtscLintRule.js.map +0 -1
  461. package/lib/structures/TtscLintRuleMap.d.ts +0 -46
  462. package/lib/structures/TtscLintRuleMap.js.map +0 -1
  463. package/lib/structures/TtscLintRuleOptions.d.ts +0 -137
  464. package/lib/structures/TtscLintRuleOptions.js.map +0 -1
  465. package/src/structures/TtscLintRule.ts +0 -160
  466. package/src/structures/TtscLintRuleMap.ts +0 -55
  467. package/src/structures/TtscLintRuleOptions.ts +0 -151
@@ -0,0 +1,113 @@
1
+ // typescript/related-getter-setter-pairs reports a `get` accessor
2
+ // whose declared return type does not match the parameter type of the
3
+ // companion `set` accessor on the same class. The accessor pair
4
+ // presents a single conceptual field at the call site — `obj.value =
5
+ // X` followed by `Y = obj.value` should round-trip with compatible
6
+ // types — but TypeScript otherwise lets the two accessors carry
7
+ // independent annotations. The rule fires when the writer cannot
8
+ // accept what the reader is about to surface.
9
+ // https://typescript-eslint.io/rules/related-getter-setter-pairs/
10
+ //
11
+ // Type-aware. The comparison resolves both sides through
12
+ // `GetTypeFromTypeNode` so type aliases, generic parameters, and union
13
+ // constituents collapse to the same set of values before the
14
+ // equality check. Without a Checker the rule short-circuits to a
15
+ // no-op the way the other type-aware rules do.
16
+ //
17
+ // The rule visits each `KindGetAccessor`. For every getter that
18
+ // carries a return-type annotation and lives inside a class
19
+ // declaration / expression, it locates the matching `set` accessor by
20
+ // name (using the same `classMembers` + `classMemberName` helpers as
21
+ // `class-literal-property-style`) and compares the annotated types
22
+ // bidirectionally — both sides must describe the same set of values
23
+ // for the accessor pair to round-trip safely.
24
+ package linthost
25
+
26
+ import (
27
+ shimast "github.com/microsoft/typescript-go/shim/ast"
28
+ )
29
+
30
+ type relatedGetterSetterPairs struct{}
31
+
32
+ func (relatedGetterSetterPairs) Name() string {
33
+ return "typescript/related-getter-setter-pairs"
34
+ }
35
+ func (relatedGetterSetterPairs) NeedsTypeChecker() bool { return true }
36
+ func (relatedGetterSetterPairs) Visits() []shimast.Kind {
37
+ return []shimast.Kind{shimast.KindGetAccessor}
38
+ }
39
+ func (relatedGetterSetterPairs) Check(ctx *Context, node *shimast.Node) {
40
+ if ctx.Checker == nil {
41
+ return
42
+ }
43
+ parent := node.Parent
44
+ if parent == nil ||
45
+ (parent.Kind != shimast.KindClassDeclaration && parent.Kind != shimast.KindClassExpression) {
46
+ return
47
+ }
48
+ getReturnType := node.Type()
49
+ if getReturnType == nil {
50
+ // No annotated return type — nothing to compare against.
51
+ return
52
+ }
53
+ name := classMemberName(node)
54
+ if name == "" {
55
+ return
56
+ }
57
+ setter := findClassSetterFor(parent, name)
58
+ if setter == nil {
59
+ return
60
+ }
61
+ setParamType := setterParameterType(setter)
62
+ if setParamType == nil {
63
+ return
64
+ }
65
+ getType := ctx.Checker.GetTypeFromTypeNode(getReturnType)
66
+ setType := ctx.Checker.GetTypeFromTypeNode(setParamType)
67
+ if getType == nil || setType == nil {
68
+ return
69
+ }
70
+ // Bidirectional assignability stands in for type identity — the
71
+ // same shape `no-unnecessary-type-assertion` uses. The accessor
72
+ // pair is safe only when reading and writing describe the same
73
+ // set of values.
74
+ if ctx.Checker.IsTypeAssignableTo(getType, setType) &&
75
+ ctx.Checker.IsTypeAssignableTo(setType, getType) {
76
+ return
77
+ }
78
+ ctx.Report(node, "Getter return type does not match the corresponding setter parameter type on `"+name+"`.")
79
+ }
80
+
81
+ // findClassSetterFor returns the `set` accessor declared on `class`
82
+ // whose name matches `name`, or nil when no such setter exists.
83
+ func findClassSetterFor(class *shimast.Node, name string) *shimast.Node {
84
+ for _, member := range classMembers(class) {
85
+ if member == nil || member.Kind != shimast.KindSetAccessor {
86
+ continue
87
+ }
88
+ if classMemberName(member) == name {
89
+ return member
90
+ }
91
+ }
92
+ return nil
93
+ }
94
+
95
+ // setterParameterType returns the type-annotation node of a `set`
96
+ // accessor's single parameter. A setter without a parameter, or with a
97
+ // parameter that carries no annotation, returns nil — the rule cannot
98
+ // compare against an inferred type.
99
+ func setterParameterType(setter *shimast.Node) *shimast.Node {
100
+ params := setter.Parameters()
101
+ if len(params) == 0 {
102
+ return nil
103
+ }
104
+ decl := params[0].AsParameterDeclaration()
105
+ if decl == nil {
106
+ return nil
107
+ }
108
+ return decl.Type
109
+ }
110
+
111
+ func init() {
112
+ Register(relatedGetterSetterPairs{})
113
+ }
@@ -0,0 +1,96 @@
1
+ // typescript/require-array-sort-compare: require an explicit comparator
2
+ // for `arr.sort()` and `arr.toSorted()`. Without a comparator, both
3
+ // methods coerce elements to strings before ordering them, so
4
+ // `[10, 2, 1].sort()` evaluates to `[1, 10, 2]` — almost never what the
5
+ // caller meant. The fix is to pass `(a, b) => a - b`-style comparator.
6
+ // typescript-eslint:
7
+ // https://typescript-eslint.io/rules/require-array-sort-compare/
8
+ package linthost
9
+
10
+ import (
11
+ shimast "github.com/microsoft/typescript-go/shim/ast"
12
+ shimchecker "github.com/microsoft/typescript-go/shim/checker"
13
+ )
14
+
15
+ // requireArraySortCompare reports `<arr>.sort()` and `<arr>.toSorted()`
16
+ // when no comparator argument is supplied. Type-aware: the Checker
17
+ // confirms the receiver is an array (or tuple) so user-defined methods
18
+ // named `sort` / `toSorted` on non-array types do not trip the rule.
19
+ type requireArraySortCompare struct{}
20
+
21
+ func (requireArraySortCompare) Name() string {
22
+ return "typescript/require-array-sort-compare"
23
+ }
24
+ func (requireArraySortCompare) NeedsTypeChecker() bool {
25
+ return true
26
+ }
27
+ func (requireArraySortCompare) Visits() []shimast.Kind {
28
+ return []shimast.Kind{shimast.KindCallExpression}
29
+ }
30
+ func (requireArraySortCompare) Check(ctx *Context, node *shimast.Node) {
31
+ if ctx.Checker == nil {
32
+ return
33
+ }
34
+ call := node.AsCallExpression()
35
+ if call == nil || call.Expression == nil {
36
+ return
37
+ }
38
+ // Only fire when the callee is a property access ending in `.sort`
39
+ // or `.toSorted` and the call passes zero arguments.
40
+ receiver, method, ok := promisePropertyAccessParts(call.Expression)
41
+ if !ok || (method != "sort" && method != "toSorted") {
42
+ return
43
+ }
44
+ if call.Arguments != nil && len(call.Arguments.Nodes) > 0 {
45
+ return
46
+ }
47
+ if receiver == nil {
48
+ return
49
+ }
50
+ t := ctx.Checker.GetTypeAtLocation(receiver)
51
+ if t == nil {
52
+ return
53
+ }
54
+ if !requireArraySortCompareIsArrayLike(ctx.Checker, t) {
55
+ return
56
+ }
57
+ ctx.Report(node, "Require an explicit compareFunction for `."+method+"()` — without one, elements are coerced to strings before being ordered.")
58
+ }
59
+
60
+ // requireArraySortCompareIsArrayLike reports whether t is provably an
61
+ // array or a tuple. The check follows the same recurse-into-constituents
62
+ // pattern as `isAwaitable` so a union like `number[] | string[]` still
63
+ // resolves to "array" via every constituent. `any` / `unknown` / `never`
64
+ // are intentionally NOT treated as array-like — they propagate from
65
+ // generic helpers and would explode the false-positive volume.
66
+ func requireArraySortCompareIsArrayLike(checker *shimchecker.Checker, t *shimchecker.Type) bool {
67
+ if checker == nil || t == nil {
68
+ return false
69
+ }
70
+ flags := t.Flags()
71
+ if flags&(shimchecker.TypeFlagsAny|shimchecker.TypeFlagsUnknown|shimchecker.TypeFlagsNever) != 0 {
72
+ return false
73
+ }
74
+ if flags&(shimchecker.TypeFlagsUnion|shimchecker.TypeFlagsIntersection) != 0 {
75
+ for _, part := range t.Types() {
76
+ if part == nil {
77
+ continue
78
+ }
79
+ if !requireArraySortCompareIsArrayLike(checker, part) {
80
+ return false
81
+ }
82
+ }
83
+ return true
84
+ }
85
+ if shimchecker.Checker_isArrayType(checker, t) {
86
+ return true
87
+ }
88
+ if shimchecker.IsTupleType(t) {
89
+ return true
90
+ }
91
+ return false
92
+ }
93
+
94
+ func init() {
95
+ Register(requireArraySortCompare{})
96
+ }
@@ -0,0 +1,127 @@
1
+ // typescript/restrict-plus-operands: the `+` operator is overloaded in
2
+ // JavaScript — it numerically adds two numbers, lexically concatenates
3
+ // two strings, and silently coerces every other combination. `1 + "a"`
4
+ // becomes `"1a"`, `null + 5` becomes `5`, `{} + 1` becomes `"[object
5
+ // Object]1"`. Each of these is almost always a bug: the author meant
6
+ // either numeric addition or explicit string concatenation, not the
7
+ // runtime's lossy fallback. typescript-eslint:
8
+ // https://typescript-eslint.io/rules/restrict-plus-operands/
9
+ package linthost
10
+
11
+ import (
12
+ shimast "github.com/microsoft/typescript-go/shim/ast"
13
+ shimchecker "github.com/microsoft/typescript-go/shim/checker"
14
+ )
15
+
16
+ // restrictPlusOperands fires on `<lhs> + <rhs>` when the operands are
17
+ // not both number-like, both string-like, or both bigint-like. The
18
+ // rule is type-aware: without a Checker it cannot prove the operand
19
+ // kinds, so it bails out to avoid false positives on plain JS or on
20
+ // files that opt out of typechecking. `any` / `unknown` / `never`
21
+ // operands are treated as unrestricted to keep false positives off
22
+ // generic helpers; the upstream rule does the same.
23
+ type restrictPlusOperands struct{}
24
+
25
+ func (restrictPlusOperands) Name() string { return "typescript/restrict-plus-operands" }
26
+ func (restrictPlusOperands) NeedsTypeChecker() bool {
27
+ return true
28
+ }
29
+ func (restrictPlusOperands) Visits() []shimast.Kind {
30
+ return []shimast.Kind{shimast.KindBinaryExpression}
31
+ }
32
+ func (restrictPlusOperands) Check(ctx *Context, node *shimast.Node) {
33
+ if ctx.Checker == nil {
34
+ return
35
+ }
36
+ expr := node.AsBinaryExpression()
37
+ if expr == nil || expr.OperatorToken == nil {
38
+ return
39
+ }
40
+ if expr.OperatorToken.Kind != shimast.KindPlusToken {
41
+ return
42
+ }
43
+ if expr.Left == nil || expr.Right == nil {
44
+ return
45
+ }
46
+ left := ctx.Checker.GetTypeAtLocation(expr.Left)
47
+ right := ctx.Checker.GetTypeAtLocation(expr.Right)
48
+ if left == nil || right == nil {
49
+ return
50
+ }
51
+ leftKind := restrictPlusOperandsKind(left)
52
+ rightKind := restrictPlusOperandsKind(right)
53
+ // Skip when either side is unconstrained (any / unknown / never /
54
+ // generic) — the rule would otherwise fire on every generic helper
55
+ // that accepts `T extends number | string`.
56
+ if leftKind == restrictPlusOperandsAny || rightKind == restrictPlusOperandsAny {
57
+ return
58
+ }
59
+ if leftKind == rightKind && leftKind != restrictPlusOperandsOther {
60
+ return
61
+ }
62
+ ctx.Report(node, "Operands of `+` must both be `number`, both `string`, or both `bigint`. Mixed or non-primitive operands are silently coerced by the runtime and almost always a bug.")
63
+ }
64
+
65
+ // restrictPlusOperandsKind classifies t as one of the four buckets the
66
+ // rule cares about. A union is accepted only when every constituent
67
+ // lands in the same primitive bucket — `string | number` is
68
+ // deliberately rejected because each branch would coerce the other
69
+ // side differently at runtime.
70
+ type restrictPlusOperandsBucket int
71
+
72
+ const (
73
+ restrictPlusOperandsOther restrictPlusOperandsBucket = iota
74
+ restrictPlusOperandsAny
75
+ restrictPlusOperandsNumber
76
+ restrictPlusOperandsString
77
+ restrictPlusOperandsBigInt
78
+ )
79
+
80
+ func restrictPlusOperandsKind(t *shimchecker.Type) restrictPlusOperandsBucket {
81
+ if t == nil {
82
+ return restrictPlusOperandsOther
83
+ }
84
+ flags := t.Flags()
85
+ if flags&(shimchecker.TypeFlagsAny|shimchecker.TypeFlagsUnknown|shimchecker.TypeFlagsNever) != 0 {
86
+ return restrictPlusOperandsAny
87
+ }
88
+ if flags&shimchecker.TypeFlagsStringLike != 0 {
89
+ return restrictPlusOperandsString
90
+ }
91
+ if flags&shimchecker.TypeFlagsNumberLike != 0 {
92
+ return restrictPlusOperandsNumber
93
+ }
94
+ if flags&shimchecker.TypeFlagsBigIntLike != 0 {
95
+ return restrictPlusOperandsBigInt
96
+ }
97
+ if flags&shimchecker.TypeFlagsUnion != 0 {
98
+ var seen restrictPlusOperandsBucket
99
+ for _, part := range t.Types() {
100
+ if part == nil {
101
+ continue
102
+ }
103
+ kind := restrictPlusOperandsKind(part)
104
+ if kind == restrictPlusOperandsAny {
105
+ return restrictPlusOperandsAny
106
+ }
107
+ if kind == restrictPlusOperandsOther {
108
+ return restrictPlusOperandsOther
109
+ }
110
+ if seen == 0 {
111
+ seen = kind
112
+ continue
113
+ }
114
+ if seen != kind {
115
+ return restrictPlusOperandsOther
116
+ }
117
+ }
118
+ if seen != 0 {
119
+ return seen
120
+ }
121
+ }
122
+ return restrictPlusOperandsOther
123
+ }
124
+
125
+ func init() {
126
+ Register(restrictPlusOperands{})
127
+ }
@@ -0,0 +1,95 @@
1
+ // typescript/restrict-template-expressions: every interpolation inside a
2
+ // template literal coerces its value through `String()` at runtime, so
3
+ // non-string-friendly types silently render as `"[object Object]"`,
4
+ // `"null"`, or `"undefined"`. The rule requires each embedded expression
5
+ // to be statically known as `string`, `number`, `bigint`, `boolean`, or
6
+ // a union of those — anything else (object types, `null`, `undefined`,
7
+ // `void`) must be converted explicitly at the call site.
8
+ // typescript-eslint:
9
+ // https://typescript-eslint.io/rules/restrict-template-expressions/
10
+ package linthost
11
+
12
+ import (
13
+ shimast "github.com/microsoft/typescript-go/shim/ast"
14
+ shimchecker "github.com/microsoft/typescript-go/shim/checker"
15
+ )
16
+
17
+ // restrictTemplateExpressions reports each `${expr}` span inside a
18
+ // template literal whose expression has a non-stringy static type.
19
+ // Type-aware: without a Checker the rule cannot tell `string | number`
20
+ // apart from `string | null`, so it bails — the AST alone never has
21
+ // enough information to decide this case.
22
+ //
23
+ // `any` / `unknown` / `never` pass through on purpose. They propagate
24
+ // from generic helpers and a strict rejection would explode the
25
+ // false-positive volume; the upstream rule makes the same choice
26
+ // behind its `allowAny` / `allowNever` options, which default to true.
27
+ type restrictTemplateExpressions struct{}
28
+
29
+ func (restrictTemplateExpressions) Name() string {
30
+ return "typescript/restrict-template-expressions"
31
+ }
32
+ func (restrictTemplateExpressions) NeedsTypeChecker() bool {
33
+ return true
34
+ }
35
+ func (restrictTemplateExpressions) Visits() []shimast.Kind {
36
+ return []shimast.Kind{shimast.KindTemplateExpression}
37
+ }
38
+ func (restrictTemplateExpressions) Check(ctx *Context, node *shimast.Node) {
39
+ if ctx.Checker == nil {
40
+ return
41
+ }
42
+ expr := node.AsTemplateExpression()
43
+ if expr == nil || expr.TemplateSpans == nil {
44
+ return
45
+ }
46
+ for _, spanNode := range expr.TemplateSpans.Nodes {
47
+ span := spanNode.AsTemplateSpan()
48
+ if span == nil || span.Expression == nil {
49
+ continue
50
+ }
51
+ t := ctx.Checker.GetTypeAtLocation(span.Expression)
52
+ if t == nil {
53
+ continue
54
+ }
55
+ if restrictTemplateExpressionsIsStringy(ctx.Checker, t) {
56
+ continue
57
+ }
58
+ ctx.Report(span.Expression, "Template interpolations must be string-like (`string`, `number`, `bigint`, or `boolean`) — convert the value explicitly to avoid coercing to `\"[object Object]\"`, `\"null\"`, or `\"undefined\"`.")
59
+ }
60
+ }
61
+
62
+ // restrictTemplateExpressionsIsStringy reports whether t is safe to
63
+ // drop into a template-literal slot — string / number / bigint /
64
+ // boolean, or a union/intersection whose every constituent is.
65
+ // `any` / `unknown` / `never` pass through (return true) so generic
66
+ // helpers propagate without lighting up the rule everywhere.
67
+ func restrictTemplateExpressionsIsStringy(checker *shimchecker.Checker, t *shimchecker.Type) bool {
68
+ if checker == nil || t == nil {
69
+ return false
70
+ }
71
+ flags := t.Flags()
72
+ if flags&(shimchecker.TypeFlagsAny|shimchecker.TypeFlagsUnknown|shimchecker.TypeFlagsNever) != 0 {
73
+ return true
74
+ }
75
+ if flags&(shimchecker.TypeFlagsUnion|shimchecker.TypeFlagsIntersection) != 0 {
76
+ for _, part := range t.Types() {
77
+ if part == nil {
78
+ continue
79
+ }
80
+ if !restrictTemplateExpressionsIsStringy(checker, part) {
81
+ return false
82
+ }
83
+ }
84
+ return true
85
+ }
86
+ const stringyMask = shimchecker.TypeFlagsStringLike |
87
+ shimchecker.TypeFlagsNumberLike |
88
+ shimchecker.TypeFlagsBigIntLike |
89
+ shimchecker.TypeFlagsBooleanLike
90
+ return flags&stringyMask != 0
91
+ }
92
+
93
+ func init() {
94
+ Register(restrictTemplateExpressions{})
95
+ }