Skip to content

Commit

Permalink
feat: interface sort keys rule
Browse files Browse the repository at this point in the history
  • Loading branch information
paibamboo committed Oct 11, 2019
1 parent d212c04 commit 4e20b1b
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 0 deletions.
50 changes: 50 additions & 0 deletions src/interfaceSortKeysRule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import * as Lint from "tslint";
import {Identifier} from "typescript";
import * as ts from "typescript";

class InterfaceSortKeysRule extends Lint.RuleWalker {
constructor(
sourceFile: ts.SourceFile,
options: Lint.IOptions
) {
super(sourceFile, options);
}

public visitInterfaceDeclaration(node: ts.InterfaceDeclaration): void {
super.visitInterfaceDeclaration(node);
this.checkAlphabetical(node);
}

public visitTypeLiteral(node: ts.TypeLiteralNode): void {
super.visitTypeLiteral(node);
this.checkAlphabetical(node);
}

private checkAlphabetical(node: ts.InterfaceDeclaration | ts.TypeLiteralNode): void {
const properties = node.members.map((member) => (member.name as Identifier).escapedText.toString());
const unsortedIndex = this.getUnsortedIndex(properties);
if (unsortedIndex !== -1) {
this.addFailureAtNode(
node.members[unsortedIndex].name as Identifier,
`The key '${(node.members[unsortedIndex].name as Identifier).escapedText}' is not sorted alphabetically`
);
}
}

private getUnsortedIndex(strs: string[], startIndex: number = 0): number {
if (strs.length < 2 || strs.length === startIndex + 1) {
return -1;
}
if (strs[startIndex] > strs[startIndex + 1]) {
return startIndex;
}
return this.getUnsortedIndex(strs, startIndex + 1);
}
}

// tslint:disable-next-line:export-name max-classes-per-file
export class Rule extends Lint.Rules.AbstractRule {
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(new InterfaceSortKeysRule(sourceFile, this.getOptions()));
}
}
49 changes: 49 additions & 0 deletions test/rules/interface-sort-keys/default/test.ts.lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
export interface IAlphabet {
aaa: string;
bbb: string;
ccc: string;
cccAaa: string;
cccc: string;
ddd: {
dddAaa: string;
dddBbb: string;
}
}

export interface IAlphabet {
aaa: string;
bbb: string;
cccAaa: string;
~~~~~~ [The key 'cccAaa' is not sorted alphabetically]
ccc: string;
cccc: string;
}

export interface IAlphabet {
aaa: string;
bbb: string;
ccc: string;
cccc: string;
~~~~ [The key 'cccc' is not sorted alphabetically]
cccAaa: string;
}

export interface IAlphabet {
aaa: string;
ddd: {
~~~ [The key 'ddd' is not sorted alphabetically]
dddAaa: string;
dddBbb: string;
}
bbb: string;
}

export interface IAlphabet {
aaa: string;
bbb: string;
ddd: {
dddBbb: string;
~~~~~~ [The key 'dddBbb' is not sorted alphabetically]
dddAaa: string;
}
}
8 changes: 8 additions & 0 deletions test/rules/interface-sort-keys/default/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"rulesDirectory": [
"../../../../lib"
],
"rules": {
"interface-sort-keys": true
}
}

0 comments on commit 4e20b1b

Please sign in to comment.