A comprehensive static code analysis tool for Angular TypeScript projects that implements TSLint rules enforcing Angular's official style guide.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Angular directive validation rules that enforce naming conventions and selector validation for directive classes and their metadata.
Enforces that classes decorated with @Directive have the suffix "Directive" (or custom) in their name.
/**
* Classes decorated with @Directive must have suffix "Directive" (or custom) in their name
* Follows Angular style guide: https://angular.io/styleguide#style-02-03
*/
export class DirectiveClassSuffixRule extends Lint.Rules.AbstractRule {
static readonly metadata: Lint.IRuleMetadata;
static readonly FAILURE_STRING: string;
static validate(className: string, suffixList: string[]): boolean;
apply(sourceFile: ts.SourceFile): Lint.RuleFailure[];
}Usage Examples:
TSLint configuration:
{
"rules": {
"directive-class-suffix": true,
"directive-class-suffix": [true, "Directive", "Dir"]
}
}Valid directive classes:
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective { }
@Directive({
selector: '[appTooltip]'
})
export class TooltipDir { } // When configured with custom suffixValidates directive selector naming conventions and format.
/**
* Directive selectors should follow specified naming conventions
* Follows Angular style guide for consistent selector patterns
*/
export class DirectiveSelectorRule extends Lint.Rules.AbstractRule {
static readonly metadata: Lint.IRuleMetadata;
static readonly FAILURE_STRING: string;
apply(sourceFile: ts.SourceFile): Lint.RuleFailure[];
}Usage Examples:
TSLint configuration:
{
"rules": {
"directive-selector": [true, "attribute", "app", "camelCase"],
"directive-selector": [true, "attribute", ["app", "lib"], "camelCase"]
}
}Valid directive selectors:
@Directive({
selector: '[appHighlight]' // attribute, app prefix, camelCase
})
export class HighlightDirective { }
@Directive({
selector: '[libDataLoader]' // attribute, lib prefix, camelCase
})
export class DataLoaderDirective { }
@Directive({
selector: '[appAutoFocus]'
})
export class AutoFocusDirective { }Invalid examples:
@Directive({
selector: '[app-highlight]' // kebab-case not allowed for camelCase config
})
export class HighlightDirective { }
@Directive({
selector: '[highlight]' // missing app prefix
})
export class HighlightDirective { }
@Directive({
selector: 'app-highlight' // element selector not allowed for attribute config
})
export class HighlightDirective { }interface DirectiveSelectorConfig {
type: "attribute" | "element";
prefix: string | string[];
style: "camelCase" | "kebab-case";
}{
"rules": {
"directive-class-suffix": [true, "Directive"],
"directive-selector": [true, "attribute", "app", "camelCase"]
}
}Multiple prefixes:
{
"rules": {
"directive-selector": [true, "attribute", ["app", "shared", "lib"], "camelCase"]
}
}@Directive({
selector: '[appIfRole]'
})
export class IfRoleDirective { }@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective { }
@Directive({
selector: '[appAutoComplete]'
})
export class AutoCompleteDirective { }Install with Tessl CLI
npx tessl i tessl/npm-codelyzer