Skip to content

Commit

Permalink
fix(eslint-plugin): [unified-signatures] type comparison and exported…
Browse files Browse the repository at this point in the history
… nodes (#839)
  • Loading branch information
uniqueiniquity authored and JamesHenry committed Aug 19, 2019
1 parent 4b0d2d9 commit 580eceb
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 7 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -60,3 +60,6 @@ jspm_packages/
.DS_Store
.idea
dist

# Editor-specific metadata folders
.vs
38 changes: 31 additions & 7 deletions packages/eslint-plugin/src/rules/unified-signatures.ts
Expand Up @@ -35,6 +35,9 @@ type ScopeNode =
| TSESTree.TSTypeLiteral;

type OverloadNode = MethodDefinition | SignatureDefinition;
type ContainingNode =
| TSESTree.ExportNamedDeclaration
| TSESTree.ExportDefaultDeclaration;

type SignatureDefinition =
| TSESTree.FunctionExpression
Expand Down Expand Up @@ -424,7 +427,8 @@ export default util.createRule({
a === b ||
(a !== undefined &&
b !== undefined &&
a.typeAnnotation.type === b.typeAnnotation.type)
sourceCode.getText(a.typeAnnotation) ===
sourceCode.getText(b.typeAnnotation))
);
}

Expand Down Expand Up @@ -495,9 +499,16 @@ export default util.createRule({
currentScope = scopes.pop()!;
}

function addOverload(signature: OverloadNode, key?: string): void {
function addOverload(
signature: OverloadNode,
key?: string,
containingNode?: ContainingNode,
): void {
key = key || getOverloadKey(signature);
if (currentScope && signature.parent === currentScope.parent && key) {
if (
currentScope &&
(containingNode || signature).parent === currentScope.parent
) {
const overloads = currentScope.overloads.get(key);
if (overloads !== undefined) {
overloads.push(signature);
Expand All @@ -521,11 +532,10 @@ export default util.createRule({
createScope(node.body, node.typeParameters);
},
TSTypeLiteral: createScope,

// collect overloads
TSDeclareFunction(node): void {
if (node.id && !node.body) {
addOverload(node, node.id.name);
}
addOverload(node, node.id.name, getExportingNode(node));
},
TSCallSignatureDeclaration: addOverload,
TSConstructSignatureDeclaration: addOverload,
Expand All @@ -540,6 +550,7 @@ export default util.createRule({
addOverload(node);
}
},

// validate scopes
'Program:exit': checkScope,
'TSModuleBlock:exit': checkScope,
Expand All @@ -550,7 +561,20 @@ export default util.createRule({
},
});

function getOverloadKey(node: OverloadNode): string | undefined {
function getExportingNode(
node: TSESTree.TSDeclareFunction,
):
| TSESTree.ExportNamedDeclaration
| TSESTree.ExportDefaultDeclaration
| undefined {
return node.parent &&
(node.parent.type === AST_NODE_TYPES.ExportNamedDeclaration ||
node.parent.type === AST_NODE_TYPES.ExportDefaultDeclaration)
? node.parent
: undefined;
}

function getOverloadKey(node: OverloadNode): string {
const info = getOverloadInfo(node);

return (
Expand Down
58 changes: 58 additions & 0 deletions packages/eslint-plugin/tests/rules/unified-signatures.test.ts
Expand Up @@ -105,6 +105,30 @@ interface I {
function f<T extends number>(x: T[]): void;
function f<T extends string>(x: T): void;
`,
// Same name, different scopes
`
declare function foo(n: number): number;
declare module "hello" {
function foo(n: number, s: string): number;
}
`,
// children of block not checked to match TSLint
`
{
function block(): number;
function block(n: number): number;
function block(n?: number): number {
return 3;
}
}
`,
`
export interface Foo {
bar(baz: string): number[];
bar(): string[];
}
`,
],
invalid: [
{
Expand Down Expand Up @@ -591,5 +615,39 @@ class Foo {
},
],
},
{
code: `
export function foo(line: number): number;
export function foo(line: number, character?: number): number;
`,
errors: [
{
messageId: 'omittingSingleParameter',
data: {
failureStringStart:
'These overloads can be combined into one signature',
},
line: 3,
column: 35,
},
],
},
{
code: `
declare function foo(line: number): number;
export function foo(line: number, character?: number): number;
`,
errors: [
{
messageId: 'omittingSingleParameter',
data: {
failureStringStart:
'These overloads can be combined into one signature',
},
line: 3,
column: 35,
},
],
},
],
});
1 change: 1 addition & 0 deletions packages/typescript-estree/src/ts-estree/ts-estree.ts
Expand Up @@ -1040,6 +1040,7 @@ export interface TSConstructSignatureDeclaration extends FunctionSignatureBase {
}

export interface TSDeclareFunction extends FunctionDeclarationBase {
id: Identifier;
type: AST_NODE_TYPES.TSDeclareFunction;
}

Expand Down

0 comments on commit 580eceb

Please sign in to comment.