Skip to content
This repository has been archived by the owner on Mar 25, 2021. It is now read-only.

Commit

Permalink
callable-types: preserve modifiers (#2962)
Browse files Browse the repository at this point in the history
  • Loading branch information
ajafff authored and adidahiya committed Aug 7, 2017
1 parent 792206b commit 6dc0d6a
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 10 deletions.
7 changes: 5 additions & 2 deletions src/rules/callableTypesRule.ts
Expand Up @@ -15,7 +15,7 @@
* limitations under the License.
*/

import { isCallSignatureDeclaration, isIdentifier, isInterfaceDeclaration, isTypeLiteralNode } from "tsutils";
import { getChildOfKind, isCallSignatureDeclaration, isIdentifier, isInterfaceDeclaration, isTypeLiteralNode } from "tsutils";
import * as ts from "typescript";

import * as Lint from "../index";
Expand Down Expand Up @@ -53,10 +53,13 @@ function walk(ctx: Lint.WalkContext<void>) {
// avoid bad parse
member.type !== undefined) {
const suggestion = renderSuggestion(member, node, ctx.sourceFile);
const fixStart = node.kind === ts.SyntaxKind.TypeLiteral
? node.getStart(ctx.sourceFile)
: getChildOfKind(node, ts.SyntaxKind.InterfaceKeyword)!.getStart(ctx.sourceFile);
ctx.addFailureAtNode(
member,
Rule.FAILURE_STRING_FACTORY(node.kind === ts.SyntaxKind.TypeLiteral ? "Type literal" : "Interface", suggestion),
Lint.Replacement.replaceNode(node, suggestion),
Lint.Replacement.replaceFromTo(fixStart, node.end, suggestion),
);
}
}
Expand Down
5 changes: 5 additions & 0 deletions test/rules/callable-types/test.ts.fix
Expand Up @@ -18,3 +18,8 @@ interface K {
(x: number): number;
(x: string): string;
}

// handle modifiers
export type I = () => void;

export type T = () => void
31 changes: 23 additions & 8 deletions test/rules/callable-types/test.ts.lint
@@ -1,40 +1,55 @@
interface I {
(): void;
~~~~~~~~~ [Interface has only a call signature — use `type I = () => void;` instead.]
~~~~~~~~~ [interface % ('type I = () => void;')]
}

interface J extends Function {
(): void;
~~~~~~~~~ [Interface has only a call signature — use `type J = () => void;` instead.]
~~~~~~~~~ [interface % ('type J = () => void;')]
}

interface K<T> {
<U extends T>(param1: U, param2: T): U;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Interface has only a call signature — use `type K<T> = <U extends T>(param1: U, param2: T) => U;` instead.]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [interface % ('type K<T> = <U extends T>(param1: U, param2: T) => U;')]
}

interface L<T> {
(): T
~~~~~ [Interface has only a call signature — use `type L<T> = () => T` instead.]
~~~~~ [interface % ('type L<T> = () => T')]
}

type T = {
(): void;
~~~~~~~~~ [Type literal has only a call signature — use `() => void` instead.]
~~~~~~~~~ [type % ('() => void')]
};

type U = {
<T>(t: T): T;
~~~~~~~~~~~~~ [Type literal has only a call signature — use `<T>(t: T) => T` instead.]
~~~~~~~~~~~~~ [type % ('<T>(t: T) => T')]
}

var fn: {(): void;};
~~~~~~~~~ [Type literal has only a call signature — use `() => void` instead.]
~~~~~~~~~ [type % ('() => void')]
function f(x: { (): void }): void;
~~~~~~~~ [Type literal has only a call signature — use `() => void` instead.]
~~~~~~~~ [type % ('() => void')]

// Overloads OK
interface K {
(x: number): number;
(x: string): string;
}

// handle modifiers
export interface I {
(): void;
~~~~~~~~~ [interface % ('type I = () => void;')]
}

export type T = {
(): void;
~~~~~~~~~ [type % ('() => void')]
}

[_base]: %s has only a call signature — use `%s` instead.
[interface]: _base % ('Interface')
[type]: _base % ('Type literal')

0 comments on commit 6dc0d6a

Please sign in to comment.