eslint-plugin-typefest 1.0.6 → 1.0.8

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 (92) hide show
  1. package/README.md +107 -91
  2. package/dist/_internal/constrained-type-at-location.d.ts.map +1 -1
  3. package/dist/_internal/constrained-type-at-location.js.map +1 -1
  4. package/dist/_internal/function-type-reference-patterns.d.ts +34 -0
  5. package/dist/_internal/function-type-reference-patterns.d.ts.map +1 -0
  6. package/dist/_internal/function-type-reference-patterns.js +103 -0
  7. package/dist/_internal/function-type-reference-patterns.js.map +1 -0
  8. package/dist/_internal/rule-catalog.d.ts.map +1 -1
  9. package/dist/_internal/rule-catalog.js +11 -0
  10. package/dist/_internal/rule-catalog.js.map +1 -1
  11. package/dist/_internal/rules-registry.d.ts.map +1 -1
  12. package/dist/_internal/rules-registry.js +22 -0
  13. package/dist/_internal/rules-registry.js.map +1 -1
  14. package/dist/_internal/set-membership.d.ts.map +1 -1
  15. package/dist/_internal/set-membership.js.map +1 -1
  16. package/dist/_internal/type-checker-compat.d.ts.map +1 -1
  17. package/dist/_internal/type-checker-compat.js.map +1 -1
  18. package/dist/_internal/type-reference-node.d.ts +8 -0
  19. package/dist/_internal/type-reference-node.d.ts.map +1 -1
  20. package/dist/_internal/type-reference-node.js +14 -0
  21. package/dist/_internal/type-reference-node.js.map +1 -1
  22. package/dist/_internal/typefest-config-references.d.ts +2 -1
  23. package/dist/_internal/typefest-config-references.d.ts.map +1 -1
  24. package/dist/_internal/typefest-config-references.js +11 -2
  25. package/dist/_internal/typefest-config-references.js.map +1 -1
  26. package/dist/_internal/typescript-eslint-node-autofix.js.map +1 -1
  27. package/dist/plugin.cjs +1077 -124
  28. package/dist/plugin.cjs.map +4 -4
  29. package/dist/plugin.d.ts.map +1 -1
  30. package/dist/plugin.js +5 -0
  31. package/dist/plugin.js.map +1 -1
  32. package/dist/rules/prefer-ts-extras-object-map-values.d.ts +14 -0
  33. package/dist/rules/prefer-ts-extras-object-map-values.d.ts.map +1 -0
  34. package/dist/rules/prefer-ts-extras-object-map-values.js +227 -0
  35. package/dist/rules/prefer-ts-extras-object-map-values.js.map +1 -0
  36. package/dist/rules/prefer-type-fest-asyncify.d.ts +7 -0
  37. package/dist/rules/prefer-type-fest-asyncify.d.ts.map +1 -0
  38. package/dist/rules/prefer-type-fest-asyncify.js +79 -0
  39. package/dist/rules/prefer-type-fest-asyncify.js.map +1 -0
  40. package/dist/rules/prefer-type-fest-conditional-except.d.ts +7 -0
  41. package/dist/rules/prefer-type-fest-conditional-except.d.ts.map +1 -0
  42. package/dist/rules/prefer-type-fest-conditional-except.js +94 -0
  43. package/dist/rules/prefer-type-fest-conditional-except.js.map +1 -0
  44. package/dist/rules/prefer-type-fest-conditional-keys.d.ts +7 -0
  45. package/dist/rules/prefer-type-fest-conditional-keys.d.ts.map +1 -0
  46. package/dist/rules/prefer-type-fest-conditional-keys.js +78 -0
  47. package/dist/rules/prefer-type-fest-conditional-keys.js.map +1 -0
  48. package/dist/rules/prefer-type-fest-distributed-omit.d.ts +7 -0
  49. package/dist/rules/prefer-type-fest-distributed-omit.d.ts.map +1 -0
  50. package/dist/rules/prefer-type-fest-distributed-omit.js +67 -0
  51. package/dist/rules/prefer-type-fest-distributed-omit.js.map +1 -0
  52. package/dist/rules/prefer-type-fest-distributed-pick.d.ts +7 -0
  53. package/dist/rules/prefer-type-fest-distributed-pick.d.ts.map +1 -0
  54. package/dist/rules/prefer-type-fest-distributed-pick.js +95 -0
  55. package/dist/rules/prefer-type-fest-distributed-pick.js.map +1 -0
  56. package/dist/rules/prefer-type-fest-merge.d.ts +7 -0
  57. package/dist/rules/prefer-type-fest-merge.d.ts.map +1 -0
  58. package/dist/rules/prefer-type-fest-merge.js +93 -0
  59. package/dist/rules/prefer-type-fest-merge.js.map +1 -0
  60. package/dist/rules/prefer-type-fest-pick-index-signature.d.ts +7 -0
  61. package/dist/rules/prefer-type-fest-pick-index-signature.d.ts.map +1 -0
  62. package/dist/rules/prefer-type-fest-pick-index-signature.js +98 -0
  63. package/dist/rules/prefer-type-fest-pick-index-signature.js.map +1 -0
  64. package/dist/rules/prefer-type-fest-set-return-type.d.ts +7 -0
  65. package/dist/rules/prefer-type-fest-set-return-type.d.ts.map +1 -0
  66. package/dist/rules/prefer-type-fest-set-return-type.js +53 -0
  67. package/dist/rules/prefer-type-fest-set-return-type.js.map +1 -0
  68. package/dist/rules/prefer-type-fest-stringified.d.ts +7 -0
  69. package/dist/rules/prefer-type-fest-stringified.d.ts.map +1 -0
  70. package/dist/rules/prefer-type-fest-stringified.js +73 -0
  71. package/dist/rules/prefer-type-fest-stringified.js.map +1 -0
  72. package/dist/rules/prefer-type-fest-union-to-intersection.d.ts +7 -0
  73. package/dist/rules/prefer-type-fest-union-to-intersection.d.ts.map +1 -0
  74. package/dist/rules/prefer-type-fest-union-to-intersection.js +114 -0
  75. package/dist/rules/prefer-type-fest-union-to-intersection.js.map +1 -0
  76. package/docs/rules/getting-started.md +2 -1
  77. package/docs/rules/guides/preset-selection-strategy.md +7 -0
  78. package/docs/rules/overview.md +1 -0
  79. package/docs/rules/prefer-ts-extras-object-map-values.md +146 -0
  80. package/docs/rules/prefer-type-fest-asyncify.md +93 -0
  81. package/docs/rules/prefer-type-fest-conditional-except.md +141 -0
  82. package/docs/rules/prefer-type-fest-conditional-keys.md +93 -0
  83. package/docs/rules/prefer-type-fest-distributed-omit.md +92 -0
  84. package/docs/rules/prefer-type-fest-distributed-pick.md +92 -0
  85. package/docs/rules/prefer-type-fest-merge.md +161 -0
  86. package/docs/rules/prefer-type-fest-pick-index-signature.md +93 -0
  87. package/docs/rules/prefer-type-fest-set-return-type.md +93 -0
  88. package/docs/rules/prefer-type-fest-stringified.md +134 -0
  89. package/docs/rules/prefer-type-fest-union-to-intersection.md +118 -0
  90. package/docs/rules/presets/experimental.md +163 -0
  91. package/docs/rules/presets/index.md +13 -0
  92. package/package.json +33 -34
package/dist/plugin.cjs CHANGED
@@ -34,13 +34,13 @@ __export(plugin_exports, {
34
34
  });
35
35
  module.exports = __toCommonJS(plugin_exports);
36
36
  var import_parser3 = __toESM(require("@typescript-eslint/parser"), 1);
37
- var import_ts_extras39 = require("ts-extras");
37
+ var import_ts_extras41 = require("ts-extras");
38
38
 
39
39
  // package.json
40
40
  var package_default = {
41
41
  $schema: "https://www.schemastore.org/package.json",
42
42
  name: "eslint-plugin-typefest",
43
- version: "1.0.6",
43
+ version: "1.0.8",
44
44
  private: false,
45
45
  description: "ESLint rules for adopting type-fest and ts-extras conventions.",
46
46
  keywords: [
@@ -254,10 +254,10 @@ var package_default = {
254
254
  "jsonc-eslint-parser": "$jsonc-eslint-parser"
255
255
  },
256
256
  dependencies: {
257
- "@typescript-eslint/parser": "^8.57.1",
258
- "@typescript-eslint/type-utils": "^8.57.1",
259
- "@typescript-eslint/utils": "^8.57.1",
260
- "ts-extras": "^0.17.0",
257
+ "@typescript-eslint/parser": "^8.57.2",
258
+ "@typescript-eslint/type-utils": "^8.57.2",
259
+ "@typescript-eslint/utils": "^8.57.2",
260
+ "ts-extras": "^0.19.0",
261
261
  "type-fest": "^5.5.0"
262
262
  },
263
263
  devDependencies: {
@@ -265,7 +265,7 @@ var package_default = {
265
265
  "@csstools/stylelint-formatter-github": "^2.0.0",
266
266
  "@docusaurus/eslint-plugin": "^3.9.2",
267
267
  "@double-great/remark-lint-alt-text": "^1.1.1",
268
- "@double-great/stylelint-a11y": "^3.4.6",
268
+ "@double-great/stylelint-a11y": "^3.4.8",
269
269
  "@eslint-community/eslint-plugin-eslint-comments": "^4.7.1",
270
270
  "@eslint-react/eslint-plugin": "^3.0.0",
271
271
  "@eslint/compat": "^2.0.3",
@@ -274,7 +274,7 @@ var package_default = {
274
274
  "@eslint/css": "^1.0.0",
275
275
  "@eslint/js": "^10.0.1",
276
276
  "@eslint/json": "^1.2.0",
277
- "@eslint/markdown": "^7.5.1",
277
+ "@eslint/markdown": "^8.0.0",
278
278
  "@html-eslint/eslint-plugin": "^0.58.1",
279
279
  "@html-eslint/parser": "^0.58.1",
280
280
  "@microsoft/eslint-plugin-sdl": "^1.1.0",
@@ -315,11 +315,12 @@ var package_default = {
315
315
  "@types/postcss-normalize": "^9.0.4",
316
316
  "@types/postcss-reporter": "^7.0.5",
317
317
  "@types/sloc": "^0.2.3",
318
- "@typescript-eslint/eslint-plugin": "^8.57.1",
319
- "@typescript-eslint/rule-tester": "^8.57.1",
320
- "@vitest/coverage-v8": "^4.1.0",
321
- "@vitest/eslint-plugin": "^1.6.12",
322
- "@vitest/ui": "^4.1.0",
318
+ "@typescript-eslint/eslint-plugin": "^8.57.2",
319
+ "@typescript-eslint/rule-tester": "^8.57.2",
320
+ "@typpi/eslint-plugin-vite": "^1.0.11",
321
+ "@vitest/coverage-v8": "^4.1.2",
322
+ "@vitest/eslint-plugin": "^1.6.13",
323
+ "@vitest/ui": "^4.1.2",
323
324
  actionlint: "^2.0.6",
324
325
  "all-contributors-cli": "^6.26.1",
325
326
  "cognitive-complexity-ts": "^0.8.1",
@@ -329,7 +330,7 @@ var package_default = {
329
330
  depcheck: "^1.4.7",
330
331
  "detect-secrets": "^1.0.6",
331
332
  eslint: "^10.1.0",
332
- "eslint-config-flat-gitignore": "^2.2.1",
333
+ "eslint-config-flat-gitignore": "^2.3.0",
333
334
  "eslint-config-prettier": "^10.1.8",
334
335
  "eslint-formatter-unix": "^9.0.1",
335
336
  "eslint-import-resolver-typescript": "^4.4.4",
@@ -345,20 +346,19 @@ var package_default = {
345
346
  "eslint-plugin-etc": "^2.0.3",
346
347
  "eslint-plugin-etc-misc": "^1.0.4",
347
348
  "eslint-plugin-file-progress-2": "^3.4.3",
349
+ "eslint-plugin-github-actions-2": "^1.0.1",
348
350
  "eslint-plugin-html": "^8.1.4",
349
- "eslint-plugin-immutable-2": "^1.0.5",
351
+ "eslint-plugin-immutable-2": "^1.0.6",
350
352
  "eslint-plugin-import-x": "^4.16.2",
351
- "eslint-plugin-jsdoc": "^62.8.0",
353
+ "eslint-plugin-jsdoc": "^62.8.1",
352
354
  "eslint-plugin-jsonc": "^3.1.2",
353
355
  "eslint-plugin-jsx-a11y": "^6.10.2",
354
356
  "eslint-plugin-listeners": "^1.5.1",
355
- "eslint-plugin-loadable-imports": "^1.0.1",
356
357
  "eslint-plugin-math": "^0.13.1",
357
358
  "eslint-plugin-module-interop": "^0.3.1",
358
359
  "eslint-plugin-n": "^17.24.0",
359
360
  "eslint-plugin-nitpick": "^0.12.0",
360
361
  "eslint-plugin-no-barrel-files": "^1.2.2",
361
- "eslint-plugin-no-explicit-type-exports": "^0.12.1",
362
362
  "eslint-plugin-no-function-declare-after-return": "^1.1.0",
363
363
  "eslint-plugin-no-lookahead-lookbehind-regexp": "^0.4.0",
364
364
  "eslint-plugin-no-only-tests": "^3.3.0",
@@ -368,7 +368,6 @@ var package_default = {
368
368
  "eslint-plugin-node-dependencies": "^2.2.0",
369
369
  "eslint-plugin-package-json": "^0.91.0",
370
370
  "eslint-plugin-perfectionist": "^5.7.0",
371
- "eslint-plugin-prefer-arrow": "^1.2.3",
372
371
  "eslint-plugin-prettier": "^5.5.5",
373
372
  "eslint-plugin-promise": "^7.2.1",
374
373
  "eslint-plugin-redos": "^4.5.0",
@@ -378,12 +377,12 @@ var package_default = {
378
377
  "eslint-plugin-security": "^4.0.0",
379
378
  "eslint-plugin-sonarjs": "^4.0.2",
380
379
  "eslint-plugin-sort-class-members": "^1.21.0",
381
- "eslint-plugin-testing-library": "^7.16.1",
380
+ "eslint-plugin-testing-library": "^7.16.2",
382
381
  "eslint-plugin-toml": "^1.3.1",
383
382
  "eslint-plugin-total-functions": "^7.1.0",
384
383
  "eslint-plugin-tsdoc": "^0.5.2",
385
384
  "eslint-plugin-tsdoc-require-2": "^1.0.6",
386
- "eslint-plugin-typefest": "^1.0.5",
385
+ "eslint-plugin-typefest": "^1.0.7",
387
386
  "eslint-plugin-undefined-css-classes": "^0.1.5",
388
387
  "eslint-plugin-unicorn": "^63.0.0",
389
388
  "eslint-plugin-unused-imports": "^4.4.1",
@@ -398,11 +397,11 @@ var package_default = {
398
397
  htmlhint: "^1.9.2",
399
398
  jscpd: "^4.0.8",
400
399
  "jsonc-eslint-parser": "^3.1.0",
401
- knip: "^6.0.1",
400
+ knip: "^6.0.6",
402
401
  leasot: "^14.4.0",
403
402
  madge: "^8.0.0",
404
403
  "markdown-link-check": "^3.14.2",
405
- "npm-check-updates": "^19.6.5",
404
+ "npm-check-updates": "^19.6.6",
406
405
  "npm-package-json-lint": "^9.1.0",
407
406
  picocolors: "^1.1.1",
408
407
  postcss: "^8.5.8",
@@ -418,7 +417,7 @@ var package_default = {
418
417
  "postcss-reporter": "^7.1.0",
419
418
  "postcss-round-subpixels": "^2.0.0",
420
419
  "postcss-scss": "^4.0.9",
421
- "postcss-sort-media-queries": "^6.3.2",
420
+ "postcss-sort-media-queries": "^6.3.3",
422
421
  "postcss-styled-jsx": "^1.0.1",
423
422
  "postcss-styled-syntax": "^0.7.1",
424
423
  "postcss-viewport-height-correction": "^1.1.1",
@@ -427,7 +426,7 @@ var package_default = {
427
426
  "prettier-plugin-interpolated-html-tags": "^2.0.1",
428
427
  "prettier-plugin-jsdoc": "^1.8.0",
429
428
  "prettier-plugin-jsdoc-type": "^0.2.0",
430
- "prettier-plugin-merge": "^0.10.0",
429
+ "prettier-plugin-merge": "^0.10.1",
431
430
  "prettier-plugin-multiline-arrays": "^4.1.5",
432
431
  "prettier-plugin-packagejson": "^3.0.2",
433
432
  "prettier-plugin-properties": "^0.3.1",
@@ -545,13 +544,13 @@ var package_default = {
545
544
  secretlint: "^11.4.0",
546
545
  sloc: "^0.3.2",
547
546
  "sort-package-json": "^3.6.1",
548
- stylelint: "^17.5.0",
547
+ stylelint: "^17.6.0",
549
548
  "stylelint-actions-formatters": "^16.3.1",
550
549
  "stylelint-checkstyle-formatter": "^0.1.2",
551
550
  "stylelint-codeframe-formatter": "^1.2.0",
552
551
  "stylelint-config-alphabetical-order": "^2.0.0",
553
552
  "stylelint-config-idiomatic-order": "^10.0.0",
554
- "stylelint-config-inspector": "^2.0.2",
553
+ "stylelint-config-inspector": "^2.0.3",
555
554
  "stylelint-config-recess-order": "^7.7.0",
556
555
  "stylelint-config-recommended": "^18.0.0",
557
556
  "stylelint-config-sass-guidelines": "^13.0.0",
@@ -576,7 +575,7 @@ var package_default = {
576
575
  "stylelint-order": "^8.1.1",
577
576
  "stylelint-plugin-defensive-css": "^2.8.0",
578
577
  "stylelint-plugin-logical-css": "^2.0.2",
579
- "stylelint-plugin-use-baseline": "^1.4.0",
578
+ "stylelint-plugin-use-baseline": "^1.4.1",
580
579
  "stylelint-prettier": "^5.0.3",
581
580
  "stylelint-react-native": "^2.7.0",
582
581
  "stylelint-scales": "^5.0.0",
@@ -585,22 +584,22 @@ var package_default = {
585
584
  "stylelint-value-no-unknown-custom-properties": "^6.1.1",
586
585
  "toml-eslint-parser": "^1.0.3",
587
586
  "ts-unused-exports": "^11.0.1",
588
- typedoc: "^0.28.17",
589
- typescript: "^5.9.3",
590
- "typescript-eslint": "^8.57.1",
587
+ typedoc: "^0.28.18",
588
+ typescript: "^6.0.2",
589
+ "typescript-eslint": "^8.57.2",
591
590
  typesync: "^0.14.3",
592
591
  vfile: "^6.0.3",
593
- vite: "^8.0.1",
592
+ vite: "^8.0.3",
594
593
  "vite-tsconfig-paths": "^6.1.1",
595
- vitest: "^4.1.0",
594
+ vitest: "^4.1.2",
596
595
  "yaml-eslint-parser": "^2.0.0",
597
596
  "yamllint-js": "^0.2.4"
598
597
  },
599
598
  peerDependencies: {
600
599
  eslint: "^9.0.0 || ^10.1.0",
601
- typescript: ">=5.0.0"
600
+ typescript: "^5.0.0 || ^6.0.0"
602
601
  },
603
- packageManager: "npm@11.12.0",
602
+ packageManager: "npm@11.12.1",
604
603
  engines: {
605
604
  node: ">=22.0.0"
606
605
  },
@@ -634,6 +633,7 @@ var createRuleDocsUrl = (ruleName) => `${RULE_DOCS_URL_BASE}${ruleName}`;
634
633
  var import_ts_extras = require("ts-extras");
635
634
  var typefestConfigNames = [
636
635
  "all",
636
+ "experimental",
637
637
  "minimal",
638
638
  "recommended",
639
639
  "recommended-type-checked",
@@ -648,6 +648,12 @@ var typefestConfigMetadataByName = {
648
648
  readmeOrder: 5,
649
649
  requiresTypeChecking: true
650
650
  },
651
+ experimental: {
652
+ icon: "\u{1F9EA}",
653
+ presetName: "typefest:experimental",
654
+ readmeOrder: 6,
655
+ requiresTypeChecking: true
656
+ },
651
657
  minimal: {
652
658
  icon: "\u{1F7E2}",
653
659
  presetName: "typefest:minimal",
@@ -675,18 +681,19 @@ var typefestConfigMetadataByName = {
675
681
  "ts-extras/type-guards": {
676
682
  icon: "\u2734\uFE0F",
677
683
  presetName: "typefest:ts-extras/type-guards",
678
- readmeOrder: 7,
684
+ readmeOrder: 8,
679
685
  requiresTypeChecking: true
680
686
  },
681
687
  "type-fest/types": {
682
688
  icon: "\u{1F4A0}",
683
689
  presetName: "typefest:type-fest/types",
684
- readmeOrder: 6,
690
+ readmeOrder: 7,
685
691
  requiresTypeChecking: false
686
692
  }
687
693
  };
688
694
  var typefestConfigReferenceToName = {
689
695
  "typefest.configs.all": "all",
696
+ "typefest.configs.experimental": "experimental",
690
697
  "typefest.configs.minimal": "minimal",
691
698
  "typefest.configs.recommended": "recommended",
692
699
  "typefest.configs.recommended-type-checked": "recommended-type-checked",
@@ -1865,6 +1872,24 @@ function getSafeLocalNameForImportedValueInScope({ importedName, imports, source
1865
1872
  }
1866
1873
  return null;
1867
1874
  }
1875
+ var getSafeLocalNameForImportedValue = ({ context, importedName, imports, referenceNode, sourceModuleName }) => {
1876
+ const sourceScope = resolveReferenceScope({
1877
+ context,
1878
+ referenceNode
1879
+ });
1880
+ if (sourceScope === null) {
1881
+ return getFirstImportedAliasName({
1882
+ importedName,
1883
+ imports
1884
+ });
1885
+ }
1886
+ return getSafeLocalNameForImportedValueInScope({
1887
+ importedName,
1888
+ imports,
1889
+ sourceModuleName,
1890
+ sourceScope
1891
+ });
1892
+ };
1868
1893
  var getSafeReplacementNameAndImportFixFactory = ({ context, importedName, imports, referenceNode, sourceModuleName }) => {
1869
1894
  const sourceScope = resolveReferenceScope({
1870
1895
  context,
@@ -2349,7 +2374,18 @@ var orderedRuleNames = [
2349
2374
  "prefer-type-fest-conditional-pick-deep",
2350
2375
  "prefer-type-fest-union-to-tuple",
2351
2376
  "prefer-type-fest-less-than",
2352
- "prefer-type-fest-less-than-or-equal"
2377
+ "prefer-type-fest-less-than-or-equal",
2378
+ "prefer-ts-extras-object-map-values",
2379
+ "prefer-type-fest-conditional-except",
2380
+ "prefer-type-fest-merge",
2381
+ "prefer-type-fest-stringified",
2382
+ "prefer-type-fest-union-to-intersection",
2383
+ "prefer-type-fest-distributed-omit",
2384
+ "prefer-type-fest-distributed-pick",
2385
+ "prefer-type-fest-set-return-type",
2386
+ "prefer-type-fest-asyncify",
2387
+ "prefer-type-fest-pick-index-signature",
2388
+ "prefer-type-fest-conditional-keys"
2353
2389
  ];
2354
2390
  var toRuleCatalogId = (ruleNumber) => `R${String(ruleNumber).padStart(3, "0")}`;
2355
2391
  var isTypefestRuleNamePattern2 = (ruleName) => ruleName.startsWith("prefer-");
@@ -5974,6 +6010,168 @@ var preferTsExtrasObjectKeysRule = createTypedRule({
5974
6010
  });
5975
6011
  var prefer_ts_extras_object_keys_default = preferTsExtrasObjectKeysRule;
5976
6012
 
6013
+ // dist/rules/prefer-ts-extras-object-map-values.js
6014
+ var getSingleExpressionArgument = (callExpression) => {
6015
+ if (callExpression.arguments.length !== 1) {
6016
+ return null;
6017
+ }
6018
+ const [argument] = callExpression.arguments;
6019
+ if (!argument || argument.type === "SpreadElement") {
6020
+ return null;
6021
+ }
6022
+ return argument;
6023
+ };
6024
+ var unwrapTransparentExpression2 = (expression) => {
6025
+ let currentExpression = expression;
6026
+ while (true) {
6027
+ if (currentExpression.type === "TSAsExpression") {
6028
+ currentExpression = currentExpression.expression;
6029
+ continue;
6030
+ }
6031
+ if (currentExpression.type === "TSNonNullExpression") {
6032
+ currentExpression = currentExpression.expression;
6033
+ continue;
6034
+ }
6035
+ if (currentExpression.type === "TSSatisfiesExpression") {
6036
+ currentExpression = currentExpression.expression;
6037
+ continue;
6038
+ }
6039
+ if (currentExpression.type === "TSTypeAssertion") {
6040
+ currentExpression = currentExpression.expression;
6041
+ continue;
6042
+ }
6043
+ return currentExpression;
6044
+ }
6045
+ };
6046
+ var getReturnedExpression = (callback) => {
6047
+ if (callback.body.type !== "BlockStatement") {
6048
+ return callback.body;
6049
+ }
6050
+ if (callback.body.body.length !== 1) {
6051
+ return null;
6052
+ }
6053
+ const [statement] = callback.body.body;
6054
+ if (statement?.type !== "ReturnStatement") {
6055
+ return null;
6056
+ }
6057
+ return statement.argument;
6058
+ };
6059
+ var getKeyIdentifierFromEntriesTupleParameter = (parameter) => {
6060
+ if (parameter.type !== "ArrayPattern" || parameter.elements.length !== 2) {
6061
+ return null;
6062
+ }
6063
+ const [firstElement, secondElement] = parameter.elements;
6064
+ if (firstElement?.type !== "Identifier" || secondElement?.type !== "Identifier") {
6065
+ return null;
6066
+ }
6067
+ return firstElement;
6068
+ };
6069
+ var isKeyPreservingMappedTupleReturn = (returnedExpression, keyIdentifier) => {
6070
+ const unwrappedExpression = unwrapTransparentExpression2(returnedExpression);
6071
+ if (unwrappedExpression.type !== "ArrayExpression" || unwrappedExpression.elements.length !== 2) {
6072
+ return false;
6073
+ }
6074
+ const [firstElement, secondElement] = unwrappedExpression.elements;
6075
+ if (!firstElement || !secondElement || firstElement.type === "SpreadElement" || secondElement.type === "SpreadElement") {
6076
+ return false;
6077
+ }
6078
+ return areEquivalentExpressions(firstElement, keyIdentifier);
6079
+ };
6080
+ var preferTsExtrasObjectMapValuesRule = createTypedRule({
6081
+ create(context) {
6082
+ const tsExtrasImports = collectDirectNamedValueImportsFromSource(context.sourceCode, TS_EXTRAS_MODULE_SOURCE);
6083
+ return {
6084
+ 'CallExpression[callee.type="Identifier"]'(node) {
6085
+ if (node.optional || node.callee.type !== "Identifier") {
6086
+ return;
6087
+ }
6088
+ const objectFromEntriesLocalName = getSafeLocalNameForImportedValue({
6089
+ context,
6090
+ importedName: "objectFromEntries",
6091
+ imports: tsExtrasImports,
6092
+ referenceNode: node,
6093
+ sourceModuleName: TS_EXTRAS_MODULE_SOURCE
6094
+ });
6095
+ if (objectFromEntriesLocalName === null || node.callee.name !== objectFromEntriesLocalName) {
6096
+ return;
6097
+ }
6098
+ const mapCallExpression = getSingleExpressionArgument(node);
6099
+ if (mapCallExpression?.type !== "CallExpression") {
6100
+ return;
6101
+ }
6102
+ const mapMemberCall = getIdentifierPropertyMemberCall({
6103
+ memberName: "map",
6104
+ node: mapCallExpression
6105
+ });
6106
+ if (mapMemberCall === null) {
6107
+ return;
6108
+ }
6109
+ const mapCallback = getSingleExpressionArgument(mapMemberCall);
6110
+ if (mapCallback?.type !== "ArrowFunctionExpression") {
6111
+ return;
6112
+ }
6113
+ const objectEntriesLocalName = getSafeLocalNameForImportedValue({
6114
+ context,
6115
+ importedName: "objectEntries",
6116
+ imports: tsExtrasImports,
6117
+ referenceNode: mapMemberCall,
6118
+ sourceModuleName: TS_EXTRAS_MODULE_SOURCE
6119
+ });
6120
+ if (objectEntriesLocalName === null) {
6121
+ return;
6122
+ }
6123
+ const entriesCallExpression = mapMemberCall.callee.object;
6124
+ if (entriesCallExpression.type !== "CallExpression" || entriesCallExpression.callee.type !== "Identifier" || entriesCallExpression.callee.name !== objectEntriesLocalName || getSingleExpressionArgument(entriesCallExpression) === null) {
6125
+ return;
6126
+ }
6127
+ if (mapCallback.params.length !== 1) {
6128
+ return;
6129
+ }
6130
+ const [tupleParameter] = mapCallback.params;
6131
+ if (tupleParameter === void 0) {
6132
+ return;
6133
+ }
6134
+ const keyIdentifier = getKeyIdentifierFromEntriesTupleParameter(tupleParameter);
6135
+ if (keyIdentifier === null) {
6136
+ return;
6137
+ }
6138
+ const returnedExpression = getReturnedExpression(mapCallback);
6139
+ if (returnedExpression === null) {
6140
+ return;
6141
+ }
6142
+ if (!isKeyPreservingMappedTupleReturn(returnedExpression, keyIdentifier)) {
6143
+ return;
6144
+ }
6145
+ reportWithOptionalFix({
6146
+ context,
6147
+ fix: null,
6148
+ messageId: "preferTsExtrasObjectMapValues",
6149
+ node
6150
+ });
6151
+ }
6152
+ };
6153
+ },
6154
+ defaultOptions: [],
6155
+ meta: {
6156
+ deprecated: false,
6157
+ docs: {
6158
+ description: "require ts-extras objectMapValues over objectFromEntries(objectEntries(...).map(...)) chains that only remap values.",
6159
+ frozen: false,
6160
+ recommended: false,
6161
+ requiresTypeChecking: false,
6162
+ typefestConfigs: ["typefest.configs.experimental"],
6163
+ url: "https://nick2bad4u.github.io/eslint-plugin-typefest/docs/rules/prefer-ts-extras-object-map-values"
6164
+ },
6165
+ messages: {
6166
+ preferTsExtrasObjectMapValues: "Prefer `objectMapValues` from `ts-extras` over `objectFromEntries(objectEntries(...).map(...))` when the map callback preserves keys and only remaps values."
6167
+ },
6168
+ schema: [],
6169
+ type: "suggestion"
6170
+ },
6171
+ name: "prefer-ts-extras-object-map-values"
6172
+ });
6173
+ var prefer_ts_extras_object_map_values_default = preferTsExtrasObjectMapValuesRule;
6174
+
5977
6175
  // dist/rules/prefer-ts-extras-object-values.js
5978
6176
  var preferTsExtrasObjectValuesRule = createTypedRule({
5979
6177
  create(context) {
@@ -6770,6 +6968,10 @@ var prefer_type_fest_array_length_default = preferTypeFestArrayLengthRule;
6770
6968
 
6771
6969
  // dist/_internal/type-reference-node.js
6772
6970
  var isIdentifierTypeReference = (node, identifierName) => node.type === "TSTypeReference" && node.typeName.type === "Identifier" && node.typeName.name === identifierName;
6971
+ var unwrapParenthesizedTypeNode = (node) => {
6972
+ const parenthesizedCandidate = node;
6973
+ return parenthesizedCandidate.type === "TSParenthesizedType" && parenthesizedCandidate.typeAnnotation !== void 0 ? unwrapParenthesizedTypeNode(parenthesizedCandidate.typeAnnotation) : node;
6974
+ };
6773
6975
 
6774
6976
  // dist/rules/prefer-type-fest-arrayable.js
6775
6977
  var ARRAY_TYPE_NAME = "Array";
@@ -6925,34 +7127,98 @@ var preferTypeFestAsyncReturnTypeRule = createTypedRule({
6925
7127
  });
6926
7128
  var prefer_type_fest_async_return_type_default = preferTypeFestAsyncReturnTypeRule;
6927
7129
 
6928
- // dist/rules/prefer-type-fest-conditional-pick-deep.js
6929
- var conditionalPickDeepAliasReplacements = {
6930
- PickDeepByType: "ConditionalPickDeep",
6931
- PickDeepByTypes: "ConditionalPickDeep"
7130
+ // dist/_internal/function-type-reference-patterns.js
7131
+ var getSingleTypeArgument2 = (node) => {
7132
+ const typeArguments = node.typeArguments?.params ?? [];
7133
+ if (typeArguments.length !== 1) {
7134
+ return null;
7135
+ }
7136
+ const [onlyTypeArgument] = typeArguments;
7137
+ return onlyTypeArgument ?? null;
6932
7138
  };
6933
- var preferTypeFestConditionalPickDeepRule = createTypedRule({
7139
+ var getParameterTypeAnnotation = (parameter) => {
7140
+ if (parameter.type === "Identifier") {
7141
+ return parameter.typeAnnotation === void 0 ? null : unwrapParenthesizedTypeNode(parameter.typeAnnotation.typeAnnotation);
7142
+ }
7143
+ if (parameter.type !== "RestElement") {
7144
+ return null;
7145
+ }
7146
+ return parameter.typeAnnotation === void 0 ? null : unwrapParenthesizedTypeNode(parameter.typeAnnotation.typeAnnotation);
7147
+ };
7148
+ var getParametersFunctionArgumentFromFunctionType = (node) => {
7149
+ if (node.params.length !== 1) {
7150
+ return null;
7151
+ }
7152
+ const [onlyParameter] = node.params;
7153
+ if (onlyParameter?.type !== "RestElement") {
7154
+ return null;
7155
+ }
7156
+ const restParameterType = getParameterTypeAnnotation(onlyParameter);
7157
+ if (restParameterType?.type !== "TSTypeReference" || !isIdentifierTypeReference(restParameterType, "Parameters")) {
7158
+ return null;
7159
+ }
7160
+ return getSingleTypeArgument2(restParameterType);
7161
+ };
7162
+ var isReturnTypeReferenceForFunction = (node, functionType) => {
7163
+ const normalizedNode = unwrapParenthesizedTypeNode(node);
7164
+ if (normalizedNode.type !== "TSTypeReference" || !isIdentifierTypeReference(normalizedNode, "ReturnType")) {
7165
+ return false;
7166
+ }
7167
+ const referencedFunctionType = getSingleTypeArgument2(normalizedNode);
7168
+ return referencedFunctionType !== null && areEquivalentTypeNodes(unwrapParenthesizedTypeNode(referencedFunctionType), unwrapParenthesizedTypeNode(functionType));
7169
+ };
7170
+ var isPromiseAwaitedReturnTypeReferenceForFunction = (node, functionType) => {
7171
+ const normalizedNode = unwrapParenthesizedTypeNode(node);
7172
+ if (normalizedNode.type !== "TSTypeReference" || !isIdentifierTypeReference(normalizedNode, "Promise")) {
7173
+ return false;
7174
+ }
7175
+ const promisedType = getSingleTypeArgument2(normalizedNode);
7176
+ if (promisedType?.type !== "TSTypeReference" || !isIdentifierTypeReference(promisedType, "Awaited")) {
7177
+ return false;
7178
+ }
7179
+ const awaitedInnerType = getSingleTypeArgument2(promisedType);
7180
+ return awaitedInnerType !== null && isReturnTypeReferenceForFunction(awaitedInnerType, functionType);
7181
+ };
7182
+
7183
+ // dist/rules/prefer-type-fest-asyncify.js
7184
+ var isAsyncifyEquivalentSetReturnTypeReference = (node, setReturnTypeLocalNames) => {
7185
+ if (node.typeName.type !== "Identifier" || !setContainsValue(setReturnTypeLocalNames, node.typeName.name)) {
7186
+ return false;
7187
+ }
7188
+ const typeArguments = node.typeArguments?.params;
7189
+ if (typeArguments?.length !== 2) {
7190
+ return false;
7191
+ }
7192
+ const [functionType, returnType] = typeArguments;
7193
+ return functionType !== void 0 && returnType !== void 0 && isPromiseAwaitedReturnTypeReferenceForFunction(returnType, functionType);
7194
+ };
7195
+ var preferTypeFestAsyncifyRule = createTypedRule({
6934
7196
  create(context) {
6935
- const importedAliasMatches = collectImportedTypeAliasMatches(context.sourceCode, conditionalPickDeepAliasReplacements);
6936
- const typeFestDirectImports = collectDirectNamedImportsFromSource(context.sourceCode, TYPE_FEST_MODULE_SOURCE);
7197
+ const setReturnTypeLocalNames = collectNamedImportLocalNamesFromSource(context.sourceCode, TYPE_FEST_MODULE_SOURCE, "SetReturnType");
6937
7198
  return {
6938
- 'TSTypeReference[typeName.type="Identifier"]'(node) {
6939
- if (node.typeName.type !== "Identifier") {
7199
+ TSFunctionType(node) {
7200
+ const functionType = getParametersFunctionArgumentFromFunctionType(node);
7201
+ const returnType = node.returnType?.typeAnnotation;
7202
+ if (functionType === null || returnType === void 0 || !isPromiseAwaitedReturnTypeReferenceForFunction(returnType, functionType)) {
6940
7203
  return;
6941
7204
  }
6942
- const importedAliasMatch = importedAliasMatches.get(node.typeName.name);
6943
- if (!importedAliasMatch) {
7205
+ reportWithOptionalFix({
7206
+ context,
7207
+ fix: null,
7208
+ messageId: "preferAsyncify",
7209
+ node
7210
+ });
7211
+ },
7212
+ 'TSTypeReference[typeName.type="Identifier"]'(node) {
7213
+ const normalizedNode = unwrapParenthesizedTypeNode(node);
7214
+ if (normalizedNode.type !== "TSTypeReference" || !isAsyncifyEquivalentSetReturnTypeReference(normalizedNode, setReturnTypeLocalNames)) {
6944
7215
  return;
6945
7216
  }
6946
- const aliasReplacementFix = createSafeTypeReferenceReplacementFix(node, importedAliasMatch.replacementName, typeFestDirectImports);
6947
7217
  reportWithOptionalFix({
6948
7218
  context,
6949
- data: {
6950
- alias: importedAliasMatch.importedName,
6951
- replacement: importedAliasMatch.replacementName
6952
- },
6953
- fix: aliasReplacementFix,
6954
- messageId: "preferConditionalPickDeep",
6955
- node
7219
+ fix: null,
7220
+ messageId: "preferAsyncify",
7221
+ node: normalizedNode
6956
7222
  });
6957
7223
  }
6958
7224
  };
@@ -6961,55 +7227,67 @@ var preferTypeFestConditionalPickDeepRule = createTypedRule({
6961
7227
  meta: {
6962
7228
  deprecated: false,
6963
7229
  docs: {
6964
- description: "require TypeFest ConditionalPickDeep over imported aliases such as PickDeepByTypes.",
7230
+ description: "require TypeFest Asyncify over async function-type wrappers built from Parameters + Promise<Awaited<ReturnType<...>>>.",
6965
7231
  frozen: false,
6966
- recommended: true,
7232
+ recommended: false,
6967
7233
  requiresTypeChecking: false,
6968
- typefestConfigs: [
6969
- "typefest.configs.recommended",
6970
- "typefest.configs.strict",
6971
- "typefest.configs.all",
6972
- "typefest.configs.type-fest/types"
6973
- ],
6974
- url: "https://nick2bad4u.github.io/eslint-plugin-typefest/docs/rules/prefer-type-fest-conditional-pick-deep"
7234
+ typefestConfigs: ["typefest.configs.experimental"],
7235
+ url: "https://nick2bad4u.github.io/eslint-plugin-typefest/docs/rules/prefer-type-fest-asyncify"
6975
7236
  },
6976
- fixable: "code",
6977
7237
  messages: {
6978
- preferConditionalPickDeep: "Prefer `{{replacement}}` from type-fest for deep conditional property filtering instead of legacy alias `{{alias}}`."
7238
+ preferAsyncify: "Prefer `Asyncify<Function>` from type-fest over manual async wrappers built from `Parameters<Function>` and `Promise<Awaited<ReturnType<Function>>>`."
6979
7239
  },
6980
7240
  schema: [],
6981
7241
  type: "suggestion"
6982
7242
  },
6983
- name: "prefer-type-fest-conditional-pick-deep"
7243
+ name: "prefer-type-fest-asyncify"
6984
7244
  });
6985
- var prefer_type_fest_conditional_pick_deep_default = preferTypeFestConditionalPickDeepRule;
7245
+ var prefer_type_fest_asyncify_default = preferTypeFestAsyncifyRule;
6986
7246
 
6987
- // dist/rules/prefer-type-fest-conditional-pick.js
6988
- var conditionalPickAliasReplacements = {
6989
- PickByTypes: "ConditionalPick"
7247
+ // dist/rules/prefer-type-fest-conditional-except.js
7248
+ var getConditionalKeysReference = (node, conditionalKeysLocalNames) => {
7249
+ const normalizedNode = unwrapParenthesizedTypeNode(node);
7250
+ if (normalizedNode.type !== "TSTypeReference" || normalizedNode.typeName.type !== "Identifier" || !setContainsValue(conditionalKeysLocalNames, normalizedNode.typeName.name)) {
7251
+ return null;
7252
+ }
7253
+ return normalizedNode;
6990
7254
  };
6991
- var preferTypeFestConditionalPickRule = createTypedRule({
7255
+ var preferTypeFestConditionalExceptRule = createTypedRule({
6992
7256
  create(context) {
6993
- const importedAliasMatches = collectImportedTypeAliasMatches(context.sourceCode, conditionalPickAliasReplacements);
6994
- const typeFestDirectImports = collectDirectNamedImportsFromSource(context.sourceCode, TYPE_FEST_MODULE_SOURCE);
7257
+ const exceptLocalNames = collectNamedImportLocalNamesFromSource(context.sourceCode, TYPE_FEST_MODULE_SOURCE, "Except");
7258
+ const conditionalKeysLocalNames = collectNamedImportLocalNamesFromSource(context.sourceCode, TYPE_FEST_MODULE_SOURCE, "ConditionalKeys");
6995
7259
  return {
6996
7260
  'TSTypeReference[typeName.type="Identifier"]'(node) {
6997
- if (node.typeName.type !== "Identifier") {
7261
+ if (node.typeName.type !== "Identifier" || !setContainsValue(exceptLocalNames, node.typeName.name)) {
6998
7262
  return;
6999
7263
  }
7000
- const importedAliasMatch = importedAliasMatches.get(node.typeName.name);
7001
- if (!importedAliasMatch) {
7264
+ const typeArguments = node.typeArguments?.params;
7265
+ if (typeArguments?.length !== 2) {
7266
+ return;
7267
+ }
7268
+ const [baseType, excludedKeysType] = typeArguments;
7269
+ if (baseType === void 0 || excludedKeysType === void 0) {
7270
+ return;
7271
+ }
7272
+ const conditionalKeysReference = getConditionalKeysReference(excludedKeysType, conditionalKeysLocalNames);
7273
+ if (conditionalKeysReference === null) {
7274
+ return;
7275
+ }
7276
+ const conditionalKeysArguments = conditionalKeysReference.typeArguments?.params;
7277
+ if (conditionalKeysArguments?.length !== 2) {
7278
+ return;
7279
+ }
7280
+ const [conditionalBaseType] = conditionalKeysArguments;
7281
+ if (conditionalBaseType === void 0) {
7282
+ return;
7283
+ }
7284
+ if (!areEquivalentTypeNodes(baseType, conditionalBaseType)) {
7002
7285
  return;
7003
7286
  }
7004
- const aliasReplacementFix = createSafeTypeReferenceReplacementFix(node, importedAliasMatch.replacementName, typeFestDirectImports);
7005
7287
  reportWithOptionalFix({
7006
7288
  context,
7007
- data: {
7008
- alias: importedAliasMatch.importedName,
7009
- replacement: importedAliasMatch.replacementName
7010
- },
7011
- fix: aliasReplacementFix,
7012
- messageId: "preferConditionalPick",
7289
+ fix: null,
7290
+ messageId: "preferConditionalExcept",
7013
7291
  node
7014
7292
  });
7015
7293
  }
@@ -7019,42 +7297,215 @@ var preferTypeFestConditionalPickRule = createTypedRule({
7019
7297
  meta: {
7020
7298
  deprecated: false,
7021
7299
  docs: {
7022
- description: "require TypeFest ConditionalPick over imported aliases such as PickByTypes.",
7300
+ description: "require TypeFest ConditionalExcept over Except<T, ConditionalKeys<T, Condition>> compositions.",
7023
7301
  frozen: false,
7024
- recommended: true,
7302
+ recommended: false,
7025
7303
  requiresTypeChecking: false,
7026
- typefestConfigs: [
7027
- "typefest.configs.recommended",
7028
- "typefest.configs.strict",
7029
- "typefest.configs.all",
7030
- "typefest.configs.type-fest/types"
7031
- ],
7032
- url: "https://nick2bad4u.github.io/eslint-plugin-typefest/docs/rules/prefer-type-fest-conditional-pick"
7304
+ typefestConfigs: ["typefest.configs.experimental"],
7305
+ url: "https://nick2bad4u.github.io/eslint-plugin-typefest/docs/rules/prefer-type-fest-conditional-except"
7033
7306
  },
7034
- fixable: "code",
7035
7307
  messages: {
7036
- preferConditionalPick: "Prefer `{{replacement}}` from type-fest to pick keys whose values match a condition instead of legacy alias `{{alias}}`."
7308
+ preferConditionalExcept: "Prefer `ConditionalExcept<Base, Condition>` from type-fest over `Except<Base, ConditionalKeys<Base, Condition>>` when excluding keys by value condition."
7037
7309
  },
7038
7310
  schema: [],
7039
7311
  type: "suggestion"
7040
7312
  },
7041
- name: "prefer-type-fest-conditional-pick"
7313
+ name: "prefer-type-fest-conditional-except"
7042
7314
  });
7043
- var prefer_type_fest_conditional_pick_default = preferTypeFestConditionalPickRule;
7315
+ var prefer_type_fest_conditional_except_default = preferTypeFestConditionalExceptRule;
7044
7316
 
7045
- // dist/rules/prefer-type-fest-constructor.js
7046
- var import_ts_extras33 = require("ts-extras");
7047
- var preferTypeFestConstructorRule = createTypedRule({
7048
- create(context) {
7049
- const typeFestDirectImports = collectDirectNamedImportsFromSource(context.sourceCode, TYPE_FEST_MODULE_SOURCE);
7050
- const { sourceCode } = context;
7051
- return {
7052
- TSConstructorType(node) {
7053
- if (node.abstract) {
7054
- return;
7055
- }
7056
- const replacementFix = !(0, import_ts_extras33.isDefined)(node.typeParameters) && (0, import_ts_extras33.isDefined)(node.returnType) ? createSafeTypeNodeTextReplacementFix(node, "Constructor", `Constructor<${sourceCode.getText(node.returnType.typeAnnotation)}, [${(0, import_ts_extras33.arrayJoin)(node.params.map((parameter) => sourceCode.getText(parameter)), ", ")}]>`, typeFestDirectImports) : null;
7057
- reportWithOptionalFix({
7317
+ // dist/rules/prefer-type-fest-conditional-keys.js
7318
+ var hasConditionalKeysKeyRemapShape = (node) => {
7319
+ if (node.operator !== "keyof" || node.typeAnnotation === void 0) {
7320
+ return false;
7321
+ }
7322
+ const normalizedOperand = unwrapParenthesizedTypeNode(node.typeAnnotation);
7323
+ if (normalizedOperand.type !== "TSMappedType" || normalizedOperand.key.type !== "Identifier") {
7324
+ return false;
7325
+ }
7326
+ const mappedKeyName = normalizedOperand.key.name;
7327
+ const constraint = normalizedOperand.constraint;
7328
+ if (constraint?.type !== "TSTypeOperator" || constraint.operator !== "keyof" || constraint.typeAnnotation === void 0) {
7329
+ return false;
7330
+ }
7331
+ const baseType = unwrapParenthesizedTypeNode(constraint.typeAnnotation);
7332
+ const keyRemapType = normalizedOperand.nameType;
7333
+ if (keyRemapType?.type !== "TSConditionalType") {
7334
+ return false;
7335
+ }
7336
+ const checkedValueType = unwrapParenthesizedTypeNode(keyRemapType.checkType);
7337
+ if (checkedValueType.type !== "TSIndexedAccessType" || !areEquivalentTypeNodes(unwrapParenthesizedTypeNode(checkedValueType.objectType), baseType) || checkedValueType.indexType.type !== "TSTypeReference" || checkedValueType.indexType.typeName.type !== "Identifier" || checkedValueType.indexType.typeName.name !== mappedKeyName) {
7338
+ return false;
7339
+ }
7340
+ return keyRemapType.trueType.type === "TSTypeReference" && keyRemapType.trueType.typeName.type === "Identifier" && keyRemapType.trueType.typeName.name === mappedKeyName && keyRemapType.falseType.type === "TSNeverKeyword";
7341
+ };
7342
+ var preferTypeFestConditionalKeysRule = createTypedRule({
7343
+ create(context) {
7344
+ return {
7345
+ TSTypeOperator(node) {
7346
+ if (!hasConditionalKeysKeyRemapShape(node)) {
7347
+ return;
7348
+ }
7349
+ reportWithOptionalFix({
7350
+ context,
7351
+ fix: null,
7352
+ messageId: "preferConditionalKeys",
7353
+ node
7354
+ });
7355
+ }
7356
+ };
7357
+ },
7358
+ defaultOptions: [],
7359
+ meta: {
7360
+ deprecated: false,
7361
+ docs: {
7362
+ description: "require TypeFest ConditionalKeys over keyof-remapped mapped types that filter keys by value condition.",
7363
+ frozen: false,
7364
+ recommended: false,
7365
+ requiresTypeChecking: false,
7366
+ typefestConfigs: ["typefest.configs.experimental"],
7367
+ url: "https://nick2bad4u.github.io/eslint-plugin-typefest/docs/rules/prefer-type-fest-conditional-keys"
7368
+ },
7369
+ messages: {
7370
+ preferConditionalKeys: "Prefer `ConditionalKeys<Base, Condition>` from type-fest over manual `keyof { [K in keyof Base as Base[K] extends Condition ? K : never]: ... }` key filters."
7371
+ },
7372
+ schema: [],
7373
+ type: "suggestion"
7374
+ },
7375
+ name: "prefer-type-fest-conditional-keys"
7376
+ });
7377
+ var prefer_type_fest_conditional_keys_default = preferTypeFestConditionalKeysRule;
7378
+
7379
+ // dist/rules/prefer-type-fest-conditional-pick-deep.js
7380
+ var conditionalPickDeepAliasReplacements = {
7381
+ PickDeepByType: "ConditionalPickDeep",
7382
+ PickDeepByTypes: "ConditionalPickDeep"
7383
+ };
7384
+ var preferTypeFestConditionalPickDeepRule = createTypedRule({
7385
+ create(context) {
7386
+ const importedAliasMatches = collectImportedTypeAliasMatches(context.sourceCode, conditionalPickDeepAliasReplacements);
7387
+ const typeFestDirectImports = collectDirectNamedImportsFromSource(context.sourceCode, TYPE_FEST_MODULE_SOURCE);
7388
+ return {
7389
+ 'TSTypeReference[typeName.type="Identifier"]'(node) {
7390
+ if (node.typeName.type !== "Identifier") {
7391
+ return;
7392
+ }
7393
+ const importedAliasMatch = importedAliasMatches.get(node.typeName.name);
7394
+ if (!importedAliasMatch) {
7395
+ return;
7396
+ }
7397
+ const aliasReplacementFix = createSafeTypeReferenceReplacementFix(node, importedAliasMatch.replacementName, typeFestDirectImports);
7398
+ reportWithOptionalFix({
7399
+ context,
7400
+ data: {
7401
+ alias: importedAliasMatch.importedName,
7402
+ replacement: importedAliasMatch.replacementName
7403
+ },
7404
+ fix: aliasReplacementFix,
7405
+ messageId: "preferConditionalPickDeep",
7406
+ node
7407
+ });
7408
+ }
7409
+ };
7410
+ },
7411
+ defaultOptions: [],
7412
+ meta: {
7413
+ deprecated: false,
7414
+ docs: {
7415
+ description: "require TypeFest ConditionalPickDeep over imported aliases such as PickDeepByTypes.",
7416
+ frozen: false,
7417
+ recommended: true,
7418
+ requiresTypeChecking: false,
7419
+ typefestConfigs: [
7420
+ "typefest.configs.recommended",
7421
+ "typefest.configs.strict",
7422
+ "typefest.configs.all",
7423
+ "typefest.configs.type-fest/types"
7424
+ ],
7425
+ url: "https://nick2bad4u.github.io/eslint-plugin-typefest/docs/rules/prefer-type-fest-conditional-pick-deep"
7426
+ },
7427
+ fixable: "code",
7428
+ messages: {
7429
+ preferConditionalPickDeep: "Prefer `{{replacement}}` from type-fest for deep conditional property filtering instead of legacy alias `{{alias}}`."
7430
+ },
7431
+ schema: [],
7432
+ type: "suggestion"
7433
+ },
7434
+ name: "prefer-type-fest-conditional-pick-deep"
7435
+ });
7436
+ var prefer_type_fest_conditional_pick_deep_default = preferTypeFestConditionalPickDeepRule;
7437
+
7438
+ // dist/rules/prefer-type-fest-conditional-pick.js
7439
+ var conditionalPickAliasReplacements = {
7440
+ PickByTypes: "ConditionalPick"
7441
+ };
7442
+ var preferTypeFestConditionalPickRule = createTypedRule({
7443
+ create(context) {
7444
+ const importedAliasMatches = collectImportedTypeAliasMatches(context.sourceCode, conditionalPickAliasReplacements);
7445
+ const typeFestDirectImports = collectDirectNamedImportsFromSource(context.sourceCode, TYPE_FEST_MODULE_SOURCE);
7446
+ return {
7447
+ 'TSTypeReference[typeName.type="Identifier"]'(node) {
7448
+ if (node.typeName.type !== "Identifier") {
7449
+ return;
7450
+ }
7451
+ const importedAliasMatch = importedAliasMatches.get(node.typeName.name);
7452
+ if (!importedAliasMatch) {
7453
+ return;
7454
+ }
7455
+ const aliasReplacementFix = createSafeTypeReferenceReplacementFix(node, importedAliasMatch.replacementName, typeFestDirectImports);
7456
+ reportWithOptionalFix({
7457
+ context,
7458
+ data: {
7459
+ alias: importedAliasMatch.importedName,
7460
+ replacement: importedAliasMatch.replacementName
7461
+ },
7462
+ fix: aliasReplacementFix,
7463
+ messageId: "preferConditionalPick",
7464
+ node
7465
+ });
7466
+ }
7467
+ };
7468
+ },
7469
+ defaultOptions: [],
7470
+ meta: {
7471
+ deprecated: false,
7472
+ docs: {
7473
+ description: "require TypeFest ConditionalPick over imported aliases such as PickByTypes.",
7474
+ frozen: false,
7475
+ recommended: true,
7476
+ requiresTypeChecking: false,
7477
+ typefestConfigs: [
7478
+ "typefest.configs.recommended",
7479
+ "typefest.configs.strict",
7480
+ "typefest.configs.all",
7481
+ "typefest.configs.type-fest/types"
7482
+ ],
7483
+ url: "https://nick2bad4u.github.io/eslint-plugin-typefest/docs/rules/prefer-type-fest-conditional-pick"
7484
+ },
7485
+ fixable: "code",
7486
+ messages: {
7487
+ preferConditionalPick: "Prefer `{{replacement}}` from type-fest to pick keys whose values match a condition instead of legacy alias `{{alias}}`."
7488
+ },
7489
+ schema: [],
7490
+ type: "suggestion"
7491
+ },
7492
+ name: "prefer-type-fest-conditional-pick"
7493
+ });
7494
+ var prefer_type_fest_conditional_pick_default = preferTypeFestConditionalPickRule;
7495
+
7496
+ // dist/rules/prefer-type-fest-constructor.js
7497
+ var import_ts_extras33 = require("ts-extras");
7498
+ var preferTypeFestConstructorRule = createTypedRule({
7499
+ create(context) {
7500
+ const typeFestDirectImports = collectDirectNamedImportsFromSource(context.sourceCode, TYPE_FEST_MODULE_SOURCE);
7501
+ const { sourceCode } = context;
7502
+ return {
7503
+ TSConstructorType(node) {
7504
+ if (node.abstract) {
7505
+ return;
7506
+ }
7507
+ const replacementFix = !(0, import_ts_extras33.isDefined)(node.typeParameters) && (0, import_ts_extras33.isDefined)(node.returnType) ? createSafeTypeNodeTextReplacementFix(node, "Constructor", `Constructor<${sourceCode.getText(node.returnType.typeAnnotation)}, [${(0, import_ts_extras33.arrayJoin)(node.params.map((parameter) => sourceCode.getText(parameter)), ", ")}]>`, typeFestDirectImports) : null;
7508
+ reportWithOptionalFix({
7058
7509
  context,
7059
7510
  fix: replacementFix,
7060
7511
  messageId: "preferConstructorSignature",
@@ -7090,6 +7541,145 @@ var preferTypeFestConstructorRule = createTypedRule({
7090
7541
  });
7091
7542
  var prefer_type_fest_constructor_default = preferTypeFestConstructorRule;
7092
7543
 
7544
+ // dist/rules/prefer-type-fest-distributed-omit.js
7545
+ var isDistributiveConditionalExtendsType = (node) => {
7546
+ const normalizedNode = unwrapParenthesizedTypeNode(node);
7547
+ return normalizedNode.type === "TSAnyKeyword" || normalizedNode.type === "TSUnknownKeyword";
7548
+ };
7549
+ var isDistributedOmitEquivalent = (node) => {
7550
+ if (node.falseType.type !== "TSNeverKeyword" || !isDistributiveConditionalExtendsType(node.extendsType)) {
7551
+ return false;
7552
+ }
7553
+ const normalizedTrueType = unwrapParenthesizedTypeNode(node.trueType);
7554
+ if (normalizedTrueType.type !== "TSTypeReference" || !isIdentifierTypeReference(normalizedTrueType, "Omit")) {
7555
+ return false;
7556
+ }
7557
+ const typeArguments = normalizedTrueType.typeArguments?.params;
7558
+ if (typeArguments?.length !== 2) {
7559
+ return false;
7560
+ }
7561
+ const [objectType] = typeArguments;
7562
+ return objectType !== void 0 && areEquivalentTypeNodes(unwrapParenthesizedTypeNode(objectType), unwrapParenthesizedTypeNode(node.checkType));
7563
+ };
7564
+ var preferTypeFestDistributedOmitRule = createTypedRule({
7565
+ create(context) {
7566
+ return {
7567
+ TSConditionalType(node) {
7568
+ if (!isDistributedOmitEquivalent(node)) {
7569
+ return;
7570
+ }
7571
+ reportWithOptionalFix({
7572
+ context,
7573
+ fix: null,
7574
+ messageId: "preferDistributedOmit",
7575
+ node
7576
+ });
7577
+ }
7578
+ };
7579
+ },
7580
+ defaultOptions: [],
7581
+ meta: {
7582
+ deprecated: false,
7583
+ docs: {
7584
+ description: "require TypeFest DistributedOmit over distributive conditional helpers of the form T extends unknown ? Omit<T, K> : never.",
7585
+ frozen: false,
7586
+ recommended: false,
7587
+ requiresTypeChecking: false,
7588
+ typefestConfigs: ["typefest.configs.experimental"],
7589
+ url: "https://nick2bad4u.github.io/eslint-plugin-typefest/docs/rules/prefer-type-fest-distributed-omit"
7590
+ },
7591
+ messages: {
7592
+ preferDistributedOmit: "Prefer `DistributedOmit<ObjectType, KeyType>` from type-fest over distributive conditional helpers like `T extends unknown ? Omit<T, K> : never`."
7593
+ },
7594
+ schema: [],
7595
+ type: "suggestion"
7596
+ },
7597
+ name: "prefer-type-fest-distributed-omit"
7598
+ });
7599
+ var prefer_type_fest_distributed_omit_default = preferTypeFestDistributedOmitRule;
7600
+
7601
+ // dist/rules/prefer-type-fest-distributed-pick.js
7602
+ var isDistributiveConditionalExtendsType2 = (node) => {
7603
+ const normalizedNode = unwrapParenthesizedTypeNode(node);
7604
+ return normalizedNode.type === "TSAnyKeyword" || normalizedNode.type === "TSUnknownKeyword";
7605
+ };
7606
+ var isKeyofBaseType = (node, baseType) => {
7607
+ const normalizedNode = unwrapParenthesizedTypeNode(node);
7608
+ if (normalizedNode.type !== "TSTypeOperator" || normalizedNode.operator !== "keyof" || normalizedNode.typeAnnotation === void 0) {
7609
+ return false;
7610
+ }
7611
+ return areEquivalentTypeNodes(unwrapParenthesizedTypeNode(normalizedNode.typeAnnotation), unwrapParenthesizedTypeNode(baseType));
7612
+ };
7613
+ var isExtractOverKeyofBaseType = (node, baseType) => {
7614
+ const normalizedNode = unwrapParenthesizedTypeNode(node);
7615
+ if (normalizedNode.type !== "TSTypeReference" || !isIdentifierTypeReference(normalizedNode, "Extract")) {
7616
+ return false;
7617
+ }
7618
+ const typeArguments = normalizedNode.typeArguments?.params;
7619
+ if (typeArguments?.length !== 2) {
7620
+ return false;
7621
+ }
7622
+ const [, extractedFromType] = typeArguments;
7623
+ return extractedFromType !== void 0 && isKeyofBaseType(extractedFromType, baseType);
7624
+ };
7625
+ var isDistributedPickEquivalent = (node) => {
7626
+ if (node.falseType.type !== "TSNeverKeyword" || !isDistributiveConditionalExtendsType2(node.extendsType)) {
7627
+ return false;
7628
+ }
7629
+ const normalizedTrueType = unwrapParenthesizedTypeNode(node.trueType);
7630
+ if (normalizedTrueType.type !== "TSTypeReference" || !isIdentifierTypeReference(normalizedTrueType, "Pick")) {
7631
+ return false;
7632
+ }
7633
+ const typeArguments = normalizedTrueType.typeArguments?.params;
7634
+ if (typeArguments?.length !== 2) {
7635
+ return false;
7636
+ }
7637
+ const [objectType, selectedKeysType] = typeArguments;
7638
+ if (objectType === void 0 || selectedKeysType === void 0) {
7639
+ return false;
7640
+ }
7641
+ if (!areEquivalentTypeNodes(unwrapParenthesizedTypeNode(objectType), unwrapParenthesizedTypeNode(node.checkType))) {
7642
+ return false;
7643
+ }
7644
+ return !isIdentifierTypeReference(unwrapParenthesizedTypeNode(selectedKeysType), "Extract") || isExtractOverKeyofBaseType(selectedKeysType, node.checkType);
7645
+ };
7646
+ var preferTypeFestDistributedPickRule = createTypedRule({
7647
+ create(context) {
7648
+ return {
7649
+ TSConditionalType(node) {
7650
+ if (!isDistributedPickEquivalent(node)) {
7651
+ return;
7652
+ }
7653
+ reportWithOptionalFix({
7654
+ context,
7655
+ fix: null,
7656
+ messageId: "preferDistributedPick",
7657
+ node
7658
+ });
7659
+ }
7660
+ };
7661
+ },
7662
+ defaultOptions: [],
7663
+ meta: {
7664
+ deprecated: false,
7665
+ docs: {
7666
+ description: "require TypeFest DistributedPick over distributive conditional helpers of the form T extends unknown ? Pick<T, K> : never.",
7667
+ frozen: false,
7668
+ recommended: false,
7669
+ requiresTypeChecking: false,
7670
+ typefestConfigs: ["typefest.configs.experimental"],
7671
+ url: "https://nick2bad4u.github.io/eslint-plugin-typefest/docs/rules/prefer-type-fest-distributed-pick"
7672
+ },
7673
+ messages: {
7674
+ preferDistributedPick: "Prefer `DistributedPick<ObjectType, KeyType>` from type-fest over distributive conditional helpers like `T extends unknown ? Pick<T, K> : never`."
7675
+ },
7676
+ schema: [],
7677
+ type: "suggestion"
7678
+ },
7679
+ name: "prefer-type-fest-distributed-pick"
7680
+ });
7681
+ var prefer_type_fest_distributed_pick_default = preferTypeFestDistributedPickRule;
7682
+
7093
7683
  // dist/rules/prefer-type-fest-except.js
7094
7684
  var OMIT_TYPE_NAME = "Omit";
7095
7685
  var exceptAliasReplacements = {
@@ -8073,6 +8663,76 @@ var preferTypeFestMergeExclusiveRule = createTypedRule({
8073
8663
  });
8074
8664
  var prefer_type_fest_merge_exclusive_default = preferTypeFestMergeExclusiveRule;
8075
8665
 
8666
+ // dist/rules/prefer-type-fest-merge.js
8667
+ var isMergeIntersectionExceptReference = (node, siblingType, exceptLocalNames) => {
8668
+ if (node.typeName.type !== "Identifier" || !setContainsValue(exceptLocalNames, node.typeName.name)) {
8669
+ return false;
8670
+ }
8671
+ const typeArguments = node.typeArguments?.params;
8672
+ if (typeArguments?.length !== 2) {
8673
+ return false;
8674
+ }
8675
+ const [, omittedKeysType] = typeArguments;
8676
+ if (omittedKeysType === void 0) {
8677
+ return false;
8678
+ }
8679
+ const normalizedOmittedKeysType = unwrapParenthesizedTypeNode(omittedKeysType);
8680
+ if (normalizedOmittedKeysType.type !== "TSTypeOperator" || normalizedOmittedKeysType.operator !== "keyof") {
8681
+ return false;
8682
+ }
8683
+ const keyedSourceType = normalizedOmittedKeysType.typeAnnotation;
8684
+ if (keyedSourceType === void 0) {
8685
+ return false;
8686
+ }
8687
+ return areEquivalentTypeNodes(unwrapParenthesizedTypeNode(siblingType), keyedSourceType);
8688
+ };
8689
+ var preferTypeFestMergeRule = createTypedRule({
8690
+ create(context) {
8691
+ const exceptLocalNames = collectNamedImportLocalNamesFromSource(context.sourceCode, TYPE_FEST_MODULE_SOURCE, "Except");
8692
+ return {
8693
+ 'TSIntersectionType > TSTypeReference[typeName.type="Identifier"]'(node) {
8694
+ const intersectionNode = node.parent;
8695
+ if (intersectionNode?.type !== "TSIntersectionType" || intersectionNode.types.length !== 2) {
8696
+ return;
8697
+ }
8698
+ const [leftType, rightType] = intersectionNode.types;
8699
+ if (leftType === void 0 || rightType === void 0) {
8700
+ return;
8701
+ }
8702
+ const siblingType = leftType === node ? rightType : leftType;
8703
+ if (!isMergeIntersectionExceptReference(node, siblingType, exceptLocalNames)) {
8704
+ return;
8705
+ }
8706
+ reportWithOptionalFix({
8707
+ context,
8708
+ fix: null,
8709
+ messageId: "preferMerge",
8710
+ node: intersectionNode
8711
+ });
8712
+ }
8713
+ };
8714
+ },
8715
+ defaultOptions: [],
8716
+ meta: {
8717
+ deprecated: false,
8718
+ docs: {
8719
+ description: "require TypeFest Merge over Except<Destination, keyof Source> & Source intersections.",
8720
+ frozen: false,
8721
+ recommended: false,
8722
+ requiresTypeChecking: false,
8723
+ typefestConfigs: ["typefest.configs.experimental"],
8724
+ url: "https://nick2bad4u.github.io/eslint-plugin-typefest/docs/rules/prefer-type-fest-merge"
8725
+ },
8726
+ messages: {
8727
+ preferMerge: "Prefer `Merge<Destination, Source>` from type-fest over `Except<Destination, keyof Source> & Source` when the second object cleanly overrides the first."
8728
+ },
8729
+ schema: [],
8730
+ type: "suggestion"
8731
+ },
8732
+ name: "prefer-type-fest-merge"
8733
+ });
8734
+ var prefer_type_fest_merge_default = preferTypeFestMergeRule;
8735
+
8076
8736
  // dist/rules/prefer-type-fest-non-empty-tuple.js
8077
8737
  var getRequiredTupleElementType = (element) => {
8078
8738
  if (element.type === "TSNamedTupleMember") {
@@ -8460,6 +9120,83 @@ var preferTypeFestPartialDeepRule = createTypedRule({
8460
9120
  });
8461
9121
  var prefer_type_fest_partial_deep_default = preferTypeFestPartialDeepRule;
8462
9122
 
9123
+ // dist/rules/prefer-type-fest-pick-index-signature.js
9124
+ var import_ts_extras37 = require("ts-extras");
9125
+ var isEmptyObjectTypeLiteral = (node) => node.type === "TSTypeLiteral" && node.members.length === 0;
9126
+ var hasPickIndexSignatureMappedTypeShape = (node) => {
9127
+ if (node.key.type !== "Identifier") {
9128
+ return false;
9129
+ }
9130
+ if (node.readonly !== false && (0, import_ts_extras37.isDefined)(node.readonly)) {
9131
+ return false;
9132
+ }
9133
+ if (node.optional !== false && (0, import_ts_extras37.isDefined)(node.optional)) {
9134
+ return false;
9135
+ }
9136
+ const constraint = node.constraint;
9137
+ if (constraint?.type !== "TSTypeOperator" || constraint.operator !== "keyof" || constraint.typeAnnotation === void 0) {
9138
+ return false;
9139
+ }
9140
+ const baseType = unwrapParenthesizedTypeNode(constraint.typeAnnotation);
9141
+ const indexedValueType = node.typeAnnotation;
9142
+ if (indexedValueType?.type !== "TSIndexedAccessType" || !areEquivalentTypeNodes(unwrapParenthesizedTypeNode(indexedValueType.objectType), baseType) || indexedValueType.indexType.type !== "TSTypeReference" || indexedValueType.indexType.typeName.type !== "Identifier" || indexedValueType.indexType.typeName.name !== node.key.name) {
9143
+ return false;
9144
+ }
9145
+ const keyRemapType = node.nameType;
9146
+ if (keyRemapType?.type !== "TSConditionalType") {
9147
+ return false;
9148
+ }
9149
+ if (!isEmptyObjectTypeLiteral(unwrapParenthesizedTypeNode(keyRemapType.checkType)) || keyRemapType.falseType.type !== "TSNeverKeyword" || keyRemapType.trueType.type !== "TSTypeReference" || keyRemapType.trueType.typeName.type !== "Identifier" || keyRemapType.trueType.typeName.name !== node.key.name) {
9150
+ return false;
9151
+ }
9152
+ const normalizedExtendsType = unwrapParenthesizedTypeNode(keyRemapType.extendsType);
9153
+ if (normalizedExtendsType.type !== "TSTypeReference" || !isIdentifierTypeReference(normalizedExtendsType, "Record")) {
9154
+ return false;
9155
+ }
9156
+ const recordTypeArguments = normalizedExtendsType.typeArguments?.params;
9157
+ if (recordTypeArguments?.length !== 2) {
9158
+ return false;
9159
+ }
9160
+ const [recordKeyType, recordValueType] = recordTypeArguments;
9161
+ return recordKeyType !== void 0 && recordValueType?.type === "TSUnknownKeyword" && recordKeyType.type === "TSTypeReference" && recordKeyType.typeName.type === "Identifier" && recordKeyType.typeName.name === node.key.name;
9162
+ };
9163
+ var preferTypeFestPickIndexSignatureRule = createTypedRule({
9164
+ create(context) {
9165
+ return {
9166
+ TSMappedType(node) {
9167
+ if (!hasPickIndexSignatureMappedTypeShape(node)) {
9168
+ return;
9169
+ }
9170
+ reportWithOptionalFix({
9171
+ context,
9172
+ fix: null,
9173
+ messageId: "preferPickIndexSignature",
9174
+ node
9175
+ });
9176
+ }
9177
+ };
9178
+ },
9179
+ defaultOptions: [],
9180
+ meta: {
9181
+ deprecated: false,
9182
+ docs: {
9183
+ description: "require TypeFest PickIndexSignature over manual mapped types that keep only index signatures.",
9184
+ frozen: false,
9185
+ recommended: false,
9186
+ requiresTypeChecking: false,
9187
+ typefestConfigs: ["typefest.configs.experimental"],
9188
+ url: "https://nick2bad4u.github.io/eslint-plugin-typefest/docs/rules/prefer-type-fest-pick-index-signature"
9189
+ },
9190
+ messages: {
9191
+ preferPickIndexSignature: "Prefer `PickIndexSignature<ObjectType>` from type-fest over manual mapped types that keep only index signatures."
9192
+ },
9193
+ schema: [],
9194
+ type: "suggestion"
9195
+ },
9196
+ name: "prefer-type-fest-pick-index-signature"
9197
+ });
9198
+ var prefer_type_fest_pick_index_signature_default = preferTypeFestPickIndexSignatureRule;
9199
+
8463
9200
  // dist/rules/prefer-type-fest-primitive.js
8464
9201
  var import_utils2 = require("@typescript-eslint/utils");
8465
9202
  var primitiveKeywordTypes = [
@@ -8533,7 +9270,7 @@ var preferTypeFestPrimitiveRule = createTypedRule({
8533
9270
  var prefer_type_fest_primitive_default = preferTypeFestPrimitiveRule;
8534
9271
 
8535
9272
  // dist/rules/prefer-type-fest-promisable.js
8536
- var import_ts_extras37 = require("ts-extras");
9273
+ var import_ts_extras38 = require("ts-extras");
8537
9274
  var PROMISABLE_TYPE_NAME = "Promisable";
8538
9275
  var PROMISE_TYPE_NAME = "Promise";
8539
9276
  var promisableAliasReplacements = {
@@ -8549,10 +9286,10 @@ var getPromiseInnerType = (node) => {
8549
9286
  return null;
8550
9287
  }
8551
9288
  const typeArguments = node.typeArguments?.params;
8552
- if (!(0, import_ts_extras37.isDefined)(typeArguments)) {
9289
+ if (!(0, import_ts_extras38.isDefined)(typeArguments)) {
8553
9290
  return null;
8554
9291
  }
8555
- return (0, import_ts_extras37.arrayFirst)(typeArguments) ?? null;
9292
+ return (0, import_ts_extras38.arrayFirst)(typeArguments) ?? null;
8556
9293
  };
8557
9294
  var preferTypeFestPromisableRule = createTypedRule({
8558
9295
  create(context, [options] = defaultOptions3) {
@@ -9314,6 +10051,49 @@ var preferTypeFestSetRequiredRule = createTypedRule({
9314
10051
  });
9315
10052
  var prefer_type_fest_set_required_default = preferTypeFestSetRequiredRule;
9316
10053
 
10054
+ // dist/rules/prefer-type-fest-set-return-type.js
10055
+ var preferTypeFestSetReturnTypeRule = createTypedRule({
10056
+ create(context) {
10057
+ return {
10058
+ TSFunctionType(node) {
10059
+ const functionType = getParametersFunctionArgumentFromFunctionType(node);
10060
+ const returnType = node.returnType?.typeAnnotation;
10061
+ if (functionType === null || returnType === void 0) {
10062
+ return;
10063
+ }
10064
+ if (isReturnTypeReferenceForFunction(returnType, functionType) || isPromiseAwaitedReturnTypeReferenceForFunction(returnType, functionType)) {
10065
+ return;
10066
+ }
10067
+ reportWithOptionalFix({
10068
+ context,
10069
+ fix: null,
10070
+ messageId: "preferSetReturnType",
10071
+ node
10072
+ });
10073
+ }
10074
+ };
10075
+ },
10076
+ defaultOptions: [],
10077
+ meta: {
10078
+ deprecated: false,
10079
+ docs: {
10080
+ description: "require TypeFest SetReturnType over direct function-type wrappers of the form (...args: Parameters<F>) => R.",
10081
+ frozen: false,
10082
+ recommended: false,
10083
+ requiresTypeChecking: false,
10084
+ typefestConfigs: ["typefest.configs.experimental"],
10085
+ url: "https://nick2bad4u.github.io/eslint-plugin-typefest/docs/rules/prefer-type-fest-set-return-type"
10086
+ },
10087
+ messages: {
10088
+ preferSetReturnType: "Prefer `SetReturnType<Function, TypeToReturn>` from type-fest over direct function-type wrappers like `(...args: Parameters<Function>) => TypeToReturn`."
10089
+ },
10090
+ schema: [],
10091
+ type: "suggestion"
10092
+ },
10093
+ name: "prefer-type-fest-set-return-type"
10094
+ });
10095
+ var prefer_type_fest_set_return_type_default = preferTypeFestSetReturnTypeRule;
10096
+
9317
10097
  // dist/rules/prefer-type-fest-simplify.js
9318
10098
  var simplifyAliasReplacements = {
9319
10099
  Expand: "Simplify",
@@ -9373,6 +10153,67 @@ var preferTypeFestSimplifyRule = createTypedRule({
9373
10153
  });
9374
10154
  var prefer_type_fest_simplify_default = preferTypeFestSimplifyRule;
9375
10155
 
10156
+ // dist/rules/prefer-type-fest-stringified.js
10157
+ var import_ts_extras39 = require("ts-extras");
10158
+ var hasStringifiedMappedTypeShape = (node) => {
10159
+ if (node.readonly !== false && (0, import_ts_extras39.isDefined)(node.readonly)) {
10160
+ return false;
10161
+ }
10162
+ if (node.optional !== false && (0, import_ts_extras39.isDefined)(node.optional)) {
10163
+ return false;
10164
+ }
10165
+ if (node.nameType !== null) {
10166
+ return false;
10167
+ }
10168
+ if (node.key.type !== "Identifier") {
10169
+ return false;
10170
+ }
10171
+ const { constraint } = node;
10172
+ if (constraint?.type !== "TSTypeOperator") {
10173
+ return false;
10174
+ }
10175
+ if (constraint.operator !== "keyof") {
10176
+ return false;
10177
+ }
10178
+ return node.typeAnnotation?.type === "TSStringKeyword";
10179
+ };
10180
+ var preferTypeFestStringifiedRule = createTypedRule({
10181
+ create(context) {
10182
+ return {
10183
+ TSMappedType(node) {
10184
+ if (!hasStringifiedMappedTypeShape(node)) {
10185
+ return;
10186
+ }
10187
+ reportWithOptionalFix({
10188
+ context,
10189
+ fix: null,
10190
+ messageId: "preferStringified",
10191
+ node
10192
+ });
10193
+ }
10194
+ };
10195
+ },
10196
+ defaultOptions: [],
10197
+ meta: {
10198
+ deprecated: false,
10199
+ docs: {
10200
+ description: "require TypeFest Stringified over manual mapped types of the form { [K in keyof T]: string }.",
10201
+ frozen: false,
10202
+ recommended: false,
10203
+ requiresTypeChecking: false,
10204
+ typefestConfigs: ["typefest.configs.experimental"],
10205
+ url: "https://nick2bad4u.github.io/eslint-plugin-typefest/docs/rules/prefer-type-fest-stringified"
10206
+ },
10207
+ messages: {
10208
+ preferStringified: "Prefer `Stringified<T>` from type-fest over manual mapped types of the form `{ [K in keyof T]: string }`."
10209
+ },
10210
+ schema: [],
10211
+ type: "suggestion"
10212
+ },
10213
+ name: "prefer-type-fest-stringified"
10214
+ });
10215
+ var prefer_type_fest_stringified_default = preferTypeFestStringifiedRule;
10216
+
9376
10217
  // dist/rules/prefer-type-fest-tagged-brands.js
9377
10218
  var BRAND_PROPERTY_NAMES = /* @__PURE__ */ new Set([
9378
10219
  "__brand",
@@ -9614,7 +10455,7 @@ var preferTypeFestTupleOfRule = createTypedRule({
9614
10455
  var prefer_type_fest_tuple_of_default = preferTypeFestTupleOfRule;
9615
10456
 
9616
10457
  // dist/rules/prefer-type-fest-union-member.js
9617
- var import_ts_extras38 = require("ts-extras");
10458
+ var import_ts_extras40 = require("ts-extras");
9618
10459
  var UNION_MEMBER_TYPE_NAME = "UnionMember";
9619
10460
  var UNION_TO_INTERSECTION_TYPE_NAME = "UnionToIntersection";
9620
10461
  var IS_NEVER_TYPE_NAME = "IsNever";
@@ -9645,7 +10486,7 @@ var getUnionArgumentTextFromExtractor = ({ node, sourceCode }) => {
9645
10486
  if (!isIdentifierTypeReferenceNamed(node.checkType, UNION_TO_INTERSECTION_TYPE_NAME)) {
9646
10487
  return null;
9647
10488
  }
9648
- const extractorArgument = (0, import_ts_extras38.arrayFirst)(node.checkType.typeArguments?.params ?? []);
10489
+ const extractorArgument = (0, import_ts_extras40.arrayFirst)(node.checkType.typeArguments?.params ?? []);
9649
10490
  if (!extractorArgument) {
9650
10491
  return null;
9651
10492
  }
@@ -9680,7 +10521,7 @@ var getUnionMemberEquivalentArgumentText = ({ node, sourceCode }) => {
9680
10521
  if (!isIdentifierTypeReferenceNamed(node.checkType, IS_NEVER_TYPE_NAME) || !isBooleanLiteralType(node.extendsType, true) || node.trueType.type !== "TSNeverKeyword") {
9681
10522
  return null;
9682
10523
  }
9683
- const guardedArgument = (0, import_ts_extras38.arrayFirst)(node.checkType.typeArguments?.params ?? []);
10524
+ const guardedArgument = (0, import_ts_extras40.arrayFirst)(node.checkType.typeArguments?.params ?? []);
9684
10525
  if (!guardedArgument) {
9685
10526
  return null;
9686
10527
  }
@@ -9743,6 +10584,102 @@ var preferTypeFestUnionMemberRule = createTypedRule({
9743
10584
  });
9744
10585
  var prefer_type_fest_union_member_default = preferTypeFestUnionMemberRule;
9745
10586
 
10587
+ // dist/rules/prefer-type-fest-union-to-intersection.js
10588
+ var isDistributiveConditionalExtendsType3 = (node) => {
10589
+ const normalizedNode = unwrapParenthesizedTypeNode(node);
10590
+ return normalizedNode.type === "TSAnyKeyword" || normalizedNode.type === "TSUnknownKeyword";
10591
+ };
10592
+ var getSingleFunctionParameterType = (node) => {
10593
+ if (node.params.length !== 1) {
10594
+ return null;
10595
+ }
10596
+ const [onlyParameter] = node.params;
10597
+ if (onlyParameter?.type !== "Identifier" || onlyParameter.typeAnnotation === void 0) {
10598
+ return null;
10599
+ }
10600
+ return unwrapParenthesizedTypeNode(onlyParameter.typeAnnotation.typeAnnotation);
10601
+ };
10602
+ var matchesUnionToIntersectionTrueType = (node, inferredTypeParameterName, unionType) => {
10603
+ const normalizedNode = unwrapParenthesizedTypeNode(node);
10604
+ if (normalizedNode.type === "TSTypeReference" && normalizedNode.typeName.type === "Identifier" && normalizedNode.typeName.name === inferredTypeParameterName) {
10605
+ return true;
10606
+ }
10607
+ if (normalizedNode.type !== "TSIntersectionType" || normalizedNode.types.length !== 2) {
10608
+ return false;
10609
+ }
10610
+ const [leftType, rightType] = normalizedNode.types;
10611
+ if (leftType === void 0 || rightType === void 0) {
10612
+ return false;
10613
+ }
10614
+ const isInferredIdentifier = (typeNode) => typeNode.type === "TSTypeReference" && typeNode.typeName.type === "Identifier" && typeNode.typeName.name === inferredTypeParameterName;
10615
+ return isInferredIdentifier(leftType) && areEquivalentTypeNodes(unwrapParenthesizedTypeNode(rightType), unwrapParenthesizedTypeNode(unionType)) || isInferredIdentifier(rightType) && areEquivalentTypeNodes(unwrapParenthesizedTypeNode(leftType), unwrapParenthesizedTypeNode(unionType));
10616
+ };
10617
+ var isUnionToIntersectionEquivalent = (node) => {
10618
+ if (node.falseType.type !== "TSNeverKeyword") {
10619
+ return false;
10620
+ }
10621
+ const distributedWrapper = unwrapParenthesizedTypeNode(node.checkType);
10622
+ if (distributedWrapper.type !== "TSConditionalType") {
10623
+ return false;
10624
+ }
10625
+ if (distributedWrapper.falseType.type !== "TSNeverKeyword" || !isDistributiveConditionalExtendsType3(distributedWrapper.extendsType)) {
10626
+ return false;
10627
+ }
10628
+ const distributedTrueType = unwrapParenthesizedTypeNode(distributedWrapper.trueType);
10629
+ if (distributedTrueType.type !== "TSFunctionType") {
10630
+ return false;
10631
+ }
10632
+ const distributedParameterType = getSingleFunctionParameterType(distributedTrueType);
10633
+ if (distributedParameterType === null || !areEquivalentTypeNodes(distributedParameterType, unwrapParenthesizedTypeNode(distributedWrapper.checkType))) {
10634
+ return false;
10635
+ }
10636
+ const extractorFunctionType = unwrapParenthesizedTypeNode(node.extendsType);
10637
+ if (extractorFunctionType.type !== "TSFunctionType") {
10638
+ return false;
10639
+ }
10640
+ const extractorParameterType = getSingleFunctionParameterType(extractorFunctionType);
10641
+ if (extractorParameterType?.type !== "TSInferType") {
10642
+ return false;
10643
+ }
10644
+ return matchesUnionToIntersectionTrueType(node.trueType, extractorParameterType.typeParameter.name.name, distributedWrapper.checkType);
10645
+ };
10646
+ var preferTypeFestUnionToIntersectionRule = createTypedRule({
10647
+ create(context) {
10648
+ return {
10649
+ TSConditionalType(node) {
10650
+ if (!isUnionToIntersectionEquivalent(node)) {
10651
+ return;
10652
+ }
10653
+ reportWithOptionalFix({
10654
+ context,
10655
+ fix: null,
10656
+ messageId: "preferUnionToIntersection",
10657
+ node
10658
+ });
10659
+ }
10660
+ };
10661
+ },
10662
+ defaultOptions: [],
10663
+ meta: {
10664
+ deprecated: false,
10665
+ docs: {
10666
+ description: "require TypeFest UnionToIntersection over custom distributive conditional helpers that turn unions into intersections.",
10667
+ frozen: false,
10668
+ recommended: false,
10669
+ requiresTypeChecking: false,
10670
+ typefestConfigs: ["typefest.configs.experimental"],
10671
+ url: "https://nick2bad4u.github.io/eslint-plugin-typefest/docs/rules/prefer-type-fest-union-to-intersection"
10672
+ },
10673
+ messages: {
10674
+ preferUnionToIntersection: "Prefer `UnionToIntersection<Union>` from type-fest over custom distributive conditional helpers that convert a union into an intersection."
10675
+ },
10676
+ schema: [],
10677
+ type: "suggestion"
10678
+ },
10679
+ name: "prefer-type-fest-union-to-intersection"
10680
+ });
10681
+ var prefer_type_fest_union_to_intersection_default = preferTypeFestUnionToIntersectionRule;
10682
+
9746
10683
  // dist/rules/prefer-type-fest-union-to-tuple.js
9747
10684
  var unionToTupleAliasReplacements = {
9748
10685
  TupleFromUnion: "UnionToTuple",
@@ -10350,6 +11287,7 @@ var typefestRuleRegistry = {
10350
11287
  "prefer-ts-extras-object-has-in": prefer_ts_extras_object_has_in_default,
10351
11288
  "prefer-ts-extras-object-has-own": prefer_ts_extras_object_has_own_default,
10352
11289
  "prefer-ts-extras-object-keys": prefer_ts_extras_object_keys_default,
11290
+ "prefer-ts-extras-object-map-values": prefer_ts_extras_object_map_values_default,
10353
11291
  "prefer-ts-extras-object-values": prefer_ts_extras_object_values_default,
10354
11292
  "prefer-ts-extras-safe-cast-to": prefer_ts_extras_safe_cast_to_default,
10355
11293
  "prefer-ts-extras-set-has": prefer_ts_extras_set_has_default,
@@ -10359,9 +11297,14 @@ var typefestRuleRegistry = {
10359
11297
  "prefer-type-fest-array-length": prefer_type_fest_array_length_default,
10360
11298
  "prefer-type-fest-arrayable": prefer_type_fest_arrayable_default,
10361
11299
  "prefer-type-fest-async-return-type": prefer_type_fest_async_return_type_default,
11300
+ "prefer-type-fest-asyncify": prefer_type_fest_asyncify_default,
11301
+ "prefer-type-fest-conditional-except": prefer_type_fest_conditional_except_default,
11302
+ "prefer-type-fest-conditional-keys": prefer_type_fest_conditional_keys_default,
10362
11303
  "prefer-type-fest-conditional-pick": prefer_type_fest_conditional_pick_default,
10363
11304
  "prefer-type-fest-conditional-pick-deep": prefer_type_fest_conditional_pick_deep_default,
10364
11305
  "prefer-type-fest-constructor": prefer_type_fest_constructor_default,
11306
+ "prefer-type-fest-distributed-omit": prefer_type_fest_distributed_omit_default,
11307
+ "prefer-type-fest-distributed-pick": prefer_type_fest_distributed_pick_default,
10365
11308
  "prefer-type-fest-except": prefer_type_fest_except_default,
10366
11309
  "prefer-type-fest-if": prefer_type_fest_if_default,
10367
11310
  "prefer-type-fest-iterable-element": prefer_type_fest_iterable_element_default,
@@ -10373,12 +11316,14 @@ var typefestRuleRegistry = {
10373
11316
  "prefer-type-fest-less-than": prefer_type_fest_less_than_default,
10374
11317
  "prefer-type-fest-less-than-or-equal": prefer_type_fest_less_than_or_equal_default,
10375
11318
  "prefer-type-fest-literal-union": prefer_type_fest_literal_union_default,
11319
+ "prefer-type-fest-merge": prefer_type_fest_merge_default,
10376
11320
  "prefer-type-fest-merge-exclusive": prefer_type_fest_merge_exclusive_default,
10377
11321
  "prefer-type-fest-non-empty-tuple": prefer_type_fest_non_empty_tuple_default,
10378
11322
  "prefer-type-fest-omit-index-signature": prefer_type_fest_omit_index_signature_default,
10379
11323
  "prefer-type-fest-optional": prefer_type_fest_optional_default,
10380
11324
  "prefer-type-fest-or-all": prefer_type_fest_or_all_default,
10381
11325
  "prefer-type-fest-partial-deep": prefer_type_fest_partial_deep_default,
11326
+ "prefer-type-fest-pick-index-signature": prefer_type_fest_pick_index_signature_default,
10382
11327
  "prefer-type-fest-primitive": prefer_type_fest_primitive_default,
10383
11328
  "prefer-type-fest-promisable": prefer_type_fest_promisable_default,
10384
11329
  "prefer-type-fest-readonly-deep": prefer_type_fest_readonly_deep_default,
@@ -10392,10 +11337,13 @@ var typefestRuleRegistry = {
10392
11337
  "prefer-type-fest-set-optional": prefer_type_fest_set_optional_default,
10393
11338
  "prefer-type-fest-set-readonly": prefer_type_fest_set_readonly_default,
10394
11339
  "prefer-type-fest-set-required": prefer_type_fest_set_required_default,
11340
+ "prefer-type-fest-set-return-type": prefer_type_fest_set_return_type_default,
10395
11341
  "prefer-type-fest-simplify": prefer_type_fest_simplify_default,
11342
+ "prefer-type-fest-stringified": prefer_type_fest_stringified_default,
10396
11343
  "prefer-type-fest-tagged-brands": prefer_type_fest_tagged_brands_default,
10397
11344
  "prefer-type-fest-tuple-of": prefer_type_fest_tuple_of_default,
10398
11345
  "prefer-type-fest-union-member": prefer_type_fest_union_member_default,
11346
+ "prefer-type-fest-union-to-intersection": prefer_type_fest_union_to_intersection_default,
10399
11347
  "prefer-type-fest-union-to-tuple": prefer_type_fest_union_to_tuple_default,
10400
11348
  "prefer-type-fest-unknown-array": prefer_type_fest_unknown_array_default,
10401
11349
  "prefer-type-fest-unknown-map": prefer_type_fest_unknown_map_default,
@@ -10418,7 +11366,7 @@ function getPackageVersion(pkg) {
10418
11366
  const version = Reflect.get(pkg, "version");
10419
11367
  return typeof version === "string" ? version : "0.0.0";
10420
11368
  }
10421
- var packageJsonValue = (0, import_ts_extras39.safeCastTo)(package_default);
11369
+ var packageJsonValue = (0, import_ts_extras41.safeCastTo)(package_default);
10422
11370
  var typeScriptParserValue = import_parser3.default;
10423
11371
  var defaultParserOptions = {
10424
11372
  ecmaVersion: "latest",
@@ -10426,10 +11374,10 @@ var defaultParserOptions = {
10426
11374
  };
10427
11375
  var normalizeParserOptions = (parserOptions) => parserOptions !== null && typeof parserOptions === "object" && !Array.isArray(parserOptions) ? { ...parserOptions } : { ...defaultParserOptions };
10428
11376
  var typefestEslintRules = typefestRules;
10429
- var isTypefestRuleName = (value) => (0, import_ts_extras39.objectHasIn)(typefestRules, value);
11377
+ var isTypefestRuleName = (value) => (0, import_ts_extras41.objectHasIn)(typefestRules, value);
10430
11378
  var typefestRuleEntries = (() => {
10431
11379
  const entries = [];
10432
- for (const [ruleName] of (0, import_ts_extras39.objectEntries)(typefestRules)) {
11380
+ for (const [ruleName] of (0, import_ts_extras41.objectEntries)(typefestRules)) {
10433
11381
  if (!isTypefestRuleName(ruleName)) {
10434
11382
  continue;
10435
11383
  }
@@ -10456,7 +11404,7 @@ var derivePresetRuleNamesByConfig = () => {
10456
11404
  const presetRuleNamesByConfig2 = createEmptyPresetRuleMap();
10457
11405
  for (const [ruleName] of typefestRuleEntries) {
10458
11406
  const configNames = rulePresetMembership[ruleName];
10459
- if (!(0, import_ts_extras39.isDefined)(configNames) || (0, import_ts_extras39.isEmpty)(configNames)) {
11407
+ if (!(0, import_ts_extras41.isDefined)(configNames) || (0, import_ts_extras41.isEmpty)(configNames)) {
10460
11408
  throw new TypeError(`Rule '${ruleName}' is missing preset membership metadata.`);
10461
11409
  }
10462
11410
  for (const configName of configNames) {
@@ -10465,6 +11413,7 @@ var derivePresetRuleNamesByConfig = () => {
10465
11413
  }
10466
11414
  return {
10467
11415
  all: dedupeRuleNames(presetRuleNamesByConfig2.all),
11416
+ experimental: dedupeRuleNames(presetRuleNamesByConfig2.experimental),
10468
11417
  minimal: dedupeRuleNames(presetRuleNamesByConfig2.minimal),
10469
11418
  recommended: dedupeRuleNames(presetRuleNamesByConfig2.recommended),
10470
11419
  "recommended-type-checked": dedupeRuleNames(presetRuleNamesByConfig2["recommended-type-checked"]),
@@ -10483,7 +11432,7 @@ function errorRulesFor(ruleNames) {
10483
11432
  var presetRuleNamesByConfig = derivePresetRuleNamesByConfig();
10484
11433
  var recommendedRuleNames = [];
10485
11434
  for (const ruleName of presetRuleNamesByConfig.recommended) {
10486
- if ((0, import_ts_extras39.setHas)(typeCheckedRuleNames, ruleName)) {
11435
+ if ((0, import_ts_extras41.setHas)(typeCheckedRuleNames, ruleName)) {
10487
11436
  continue;
10488
11437
  }
10489
11438
  recommendedRuleNames.push(ruleName);
@@ -10494,6 +11443,10 @@ var recommendedTypeCheckedRuleNames = dedupeRuleNames([
10494
11443
  ]);
10495
11444
  var effectivePresetRuleNamesByConfig = {
10496
11445
  ...presetRuleNamesByConfig,
11446
+ experimental: dedupeRuleNames([
11447
+ ...presetRuleNamesByConfig.all,
11448
+ ...presetRuleNamesByConfig.experimental
11449
+ ]),
10497
11450
  recommended: recommendedRuleNames,
10498
11451
  "recommended-type-checked": recommendedTypeCheckedRuleNames
10499
11452
  };
@@ -10501,7 +11454,7 @@ function withTypefestPlugin(config, plugin, options) {
10501
11454
  const existingLanguageOptions = config.languageOptions ?? {};
10502
11455
  const existingParserOptions = existingLanguageOptions["parserOptions"];
10503
11456
  const parserOptions = normalizeParserOptions(existingParserOptions);
10504
- if (options.requiresTypeChecking && !(0, import_ts_extras39.objectHasIn)(parserOptions, "projectService")) {
11457
+ if (options.requiresTypeChecking && !(0, import_ts_extras41.objectHasIn)(parserOptions, "projectService")) {
10505
11458
  Reflect.set(parserOptions, "projectService", true);
10506
11459
  }
10507
11460
  const languageOptions = {