Skip to content

Commit 580eceb

Browse files
uniqueiniquityJamesHenry
authored andcommitted
fix(eslint-plugin): [unified-signatures] type comparison and exported nodes (typescript-eslint#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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy