|
1 | 1 | import type { TSESTree } from '@typescript-eslint/utils'; |
2 | 2 |
|
3 | | -import { AST_NODE_TYPES } from '@typescript-eslint/utils'; |
| 3 | +import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; |
4 | 4 |
|
5 | 5 | import type { Equal } from '../util'; |
6 | 6 |
|
@@ -61,6 +61,7 @@ export type MessageIds = |
61 | 61 | export type Options = [ |
62 | 62 | { |
63 | 63 | ignoreDifferentlyNamedParameters?: boolean; |
| 64 | + ignoreOverloadsWithDifferentJSDoc?: boolean; |
64 | 65 | }, |
65 | 66 | ]; |
66 | 67 |
|
@@ -91,16 +92,25 @@ export default createRule<Options, MessageIds>({ |
91 | 92 | description: |
92 | 93 | 'Whether two parameters with different names at the same index should be considered different even if their types are the same.', |
93 | 94 | }, |
| 95 | + ignoreOverloadsWithDifferentJSDoc: { |
| 96 | + type: 'boolean', |
| 97 | + description: |
| 98 | + 'Whether two overloads with different JSDoc comments should be considered different even if their parameter and return types are the same.', |
| 99 | + }, |
94 | 100 | }, |
95 | 101 | }, |
96 | 102 | ], |
97 | 103 | }, |
98 | 104 | defaultOptions: [ |
99 | 105 | { |
100 | 106 | ignoreDifferentlyNamedParameters: false, |
| 107 | + ignoreOverloadsWithDifferentJSDoc: false, |
101 | 108 | }, |
102 | 109 | ], |
103 | | - create(context, [{ ignoreDifferentlyNamedParameters }]) { |
| 110 | + create( |
| 111 | + context, |
| 112 | + [{ ignoreDifferentlyNamedParameters, ignoreOverloadsWithDifferentJSDoc }], |
| 113 | + ) { |
104 | 114 | //---------------------------------------------------------------------- |
105 | 115 | // Helpers |
106 | 116 | //---------------------------------------------------------------------- |
@@ -230,6 +240,15 @@ export default createRule<Options, MessageIds>({ |
230 | 240 | } |
231 | 241 | } |
232 | 242 |
|
| 243 | + if (ignoreOverloadsWithDifferentJSDoc) { |
| 244 | + const aComment = getBlockCommentForNode(getExportingNode(a) ?? a); |
| 245 | + const bComment = getBlockCommentForNode(getExportingNode(b) ?? b); |
| 246 | + |
| 247 | + if (aComment?.value !== bComment?.value) { |
| 248 | + return false; |
| 249 | + } |
| 250 | + } |
| 251 | + |
233 | 252 | return ( |
234 | 253 | typesAreEqual(a.returnType, b.returnType) && |
235 | 254 | // Must take the same type parameters. |
@@ -522,6 +541,18 @@ export default createRule<Options, MessageIds>({ |
522 | 541 | currentScope = scopes.pop(); |
523 | 542 | } |
524 | 543 |
|
| 544 | + /** |
| 545 | + * @returns the first valid JSDoc comment annotating `node` |
| 546 | + */ |
| 547 | + function getBlockCommentForNode( |
| 548 | + node: TSESTree.Node, |
| 549 | + ): TSESTree.Comment | undefined { |
| 550 | + return context.sourceCode |
| 551 | + .getCommentsBefore(node) |
| 552 | + .reverse() |
| 553 | + .find(comment => comment.type === AST_TOKEN_TYPES.Block); |
| 554 | + } |
| 555 | + |
525 | 556 | function addOverload( |
526 | 557 | signature: OverloadNode, |
527 | 558 | key?: string, |
@@ -590,7 +621,7 @@ export default createRule<Options, MessageIds>({ |
590 | 621 | }); |
591 | 622 |
|
592 | 623 | function getExportingNode( |
593 | | - node: TSESTree.TSDeclareFunction, |
| 624 | + node: SignatureDefinition, |
594 | 625 | ): |
595 | 626 | | TSESTree.ExportDefaultDeclaration |
596 | 627 | | TSESTree.ExportNamedDeclaration |
|
0 commit comments