Skip to content

Commit 580eceb

Browse files
uniqueiniquityJamesHenry
authored andcommitted
fix(eslint-plugin): [unified-signatures] type comparison and exported nodes (#839)
1 parent 4b0d2d9 commit 580eceb

File tree

4 files changed

+93
-7
lines changed

4 files changed

+93
-7
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,6 @@ jspm_packages/
6060
.DS_Store
6161
.idea
6262
dist
63+
64+
# Editor-specific metadata folders
65+
.vs

packages/eslint-plugin/src/rules/unified-signatures.ts

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ type ScopeNode =
3535
| TSESTree.TSTypeLiteral;
3636

3737
type OverloadNode = MethodDefinition | SignatureDefinition;
38+
type ContainingNode =
39+
| TSESTree.ExportNamedDeclaration
40+
| TSESTree.ExportDefaultDeclaration;
3841

3942
type SignatureDefinition =
4043
| TSESTree.FunctionExpression
@@ -424,7 +427,8 @@ export default util.createRule({
424427
a === b ||
425428
(a !== undefined &&
426429
b !== undefined &&
427-
a.typeAnnotation.type === b.typeAnnotation.type)
430+
sourceCode.getText(a.typeAnnotation) ===
431+
sourceCode.getText(b.typeAnnotation))
428432
);
429433
}
430434

@@ -495,9 +499,16 @@ export default util.createRule({
495499
currentScope = scopes.pop()!;
496500
}
497501

498-
function addOverload(signature: OverloadNode, key?: string): void {
502+
function addOverload(
503+
signature: OverloadNode,
504+
key?: string,
505+
containingNode?: ContainingNode,
506+
): void {
499507
key = key || getOverloadKey(signature);
500-
if (currentScope && signature.parent === currentScope.parent && key) {
508+
if (
509+
currentScope &&
510+
(containingNode || signature).parent === currentScope.parent
511+
) {
501512
const overloads = currentScope.overloads.get(key);
502513
if (overloads !== undefined) {
503514
overloads.push(signature);
@@ -521,11 +532,10 @@ export default util.createRule({
521532
createScope(node.body, node.typeParameters);
522533
},
523534
TSTypeLiteral: createScope,
535+
524536
// collect overloads
525537
TSDeclareFunction(node): void {
526-
if (node.id && !node.body) {
527-
addOverload(node, node.id.name);
528-
}
538+
addOverload(node, node.id.name, getExportingNode(node));
529539
},
530540
TSCallSignatureDeclaration: addOverload,
531541
TSConstructSignatureDeclaration: addOverload,
@@ -540,6 +550,7 @@ export default util.createRule({
540550
addOverload(node);
541551
}
542552
},
553+
543554
// validate scopes
544555
'Program:exit': checkScope,
545556
'TSModuleBlock:exit': checkScope,
@@ -550,7 +561,20 @@ export default util.createRule({
550561
},
551562
});
552563

553-
function getOverloadKey(node: OverloadNode): string | undefined {
564+
function getExportingNode(
565+
node: TSESTree.TSDeclareFunction,
566+
):
567+
| TSESTree.ExportNamedDeclaration
568+
| TSESTree.ExportDefaultDeclaration
569+
| undefined {
570+
return node.parent &&
571+
(node.parent.type === AST_NODE_TYPES.ExportNamedDeclaration ||
572+
node.parent.type === AST_NODE_TYPES.ExportDefaultDeclaration)
573+
? node.parent
574+
: undefined;
575+
}
576+
577+
function getOverloadKey(node: OverloadNode): string {
554578
const info = getOverloadInfo(node);
555579

556580
return (

packages/eslint-plugin/tests/rules/unified-signatures.test.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,30 @@ interface I {
105105
function f<T extends number>(x: T[]): void;
106106
function f<T extends string>(x: T): void;
107107
`,
108+
// Same name, different scopes
109+
`
110+
declare function foo(n: number): number;
111+
112+
declare module "hello" {
113+
function foo(n: number, s: string): number;
114+
}
115+
`,
116+
// children of block not checked to match TSLint
117+
`
118+
{
119+
function block(): number;
120+
function block(n: number): number;
121+
function block(n?: number): number {
122+
return 3;
123+
}
124+
}
125+
`,
126+
`
127+
export interface Foo {
128+
bar(baz: string): number[];
129+
bar(): string[];
130+
}
131+
`,
108132
],
109133
invalid: [
110134
{
@@ -591,5 +615,39 @@ class Foo {
591615
},
592616
],
593617
},
618+
{
619+
code: `
620+
export function foo(line: number): number;
621+
export function foo(line: number, character?: number): number;
622+
`,
623+
errors: [
624+
{
625+
messageId: 'omittingSingleParameter',
626+
data: {
627+
failureStringStart:
628+
'These overloads can be combined into one signature',
629+
},
630+
line: 3,
631+
column: 35,
632+
},
633+
],
634+
},
635+
{
636+
code: `
637+
declare function foo(line: number): number;
638+
export function foo(line: number, character?: number): number;
639+
`,
640+
errors: [
641+
{
642+
messageId: 'omittingSingleParameter',
643+
data: {
644+
failureStringStart:
645+
'These overloads can be combined into one signature',
646+
},
647+
line: 3,
648+
column: 35,
649+
},
650+
],
651+
},
594652
],
595653
});

packages/typescript-estree/src/ts-estree/ts-estree.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,6 +1040,7 @@ export interface TSConstructSignatureDeclaration extends FunctionSignatureBase {
10401040
}
10411041

10421042
export interface TSDeclareFunction extends FunctionDeclarationBase {
1043+
id: Identifier;
10431044
type: AST_NODE_TYPES.TSDeclareFunction;
10441045
}
10451046

0 commit comments

Comments
 (0)