CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-codelyzer

A comprehensive static code analysis tool for Angular TypeScript projects that implements TSLint rules enforcing Angular's official style guide.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

template-rules.mddocs/

Template Rules

Angular template validation rules that cover accessibility, performance, correctness, and best practices for Angular component templates.

Capabilities

Template Banana in Box Rule

Prevents common two-way binding syntax mistakes (banana in a box pattern).

/**
 * Ensures correct two-way binding syntax [()] instead of ([])
 * Prevents common template binding mistakes
 */
export class TemplateBananaInBoxRule 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": {
    "template-banana-in-box": true
  }
}

Correct two-way binding:

<input [(ngModel)]="value">

Incorrect (banana in box):

<input ([ngModel])="value">  <!-- Wrong: parentheses inside brackets -->

Template No Call Expression Rule

Prevents function calls in Angular templates for performance reasons.

/**
 * Prevents function calls in templates that execute on every change detection
 * Improves application performance by avoiding unnecessary computations
 */
export class TemplateNoCallExpressionRule extends Lint.Rules.AbstractRule {
  static readonly metadata: Lint.IRuleMetadata;
  static readonly FAILURE_STRING: string;
  apply(sourceFile: ts.SourceFile): Lint.RuleFailure[];
}

Usage Examples:

Bad (function calls in template):

<div>{{ getFullName() }}</div>
<button (click)="calculate().then(handleResult)">Calculate</button>

Good (use properties or pipes):

<div>{{ fullName }}</div>
<div>{{ userData | fullName }}</div>
<button (click)="handleCalculate()">Calculate</button>

Template No Any Rule

Prevents use of 'any' type in Angular templates.

/**
 * Prevents use of '$any()' type assertion in templates
 * Maintains type safety in Angular templates
 */
export class TemplateNoAnyRule extends Lint.Rules.AbstractRule {
  static readonly metadata: Lint.IRuleMetadata;
  static readonly FAILURE_STRING: string;
  apply(sourceFile: ts.SourceFile): Lint.RuleFailure[];
}

Template No Negated Async Rule

Prevents negation of async pipe results which can cause issues.

/**
 * Prevents negating async pipe results in templates
 * Avoids potential issues with truthy/falsy evaluation of observables
 */
export class TemplateNoNegatedAsyncRule extends Lint.Rules.AbstractRule {
  static readonly metadata: Lint.IRuleMetadata;
  static readonly FAILURE_STRING: string;
  apply(sourceFile: ts.SourceFile): Lint.RuleFailure[];
}

Usage Examples:

Bad:

<div *ngIf="!(data$ | async)">No data</div>

Good:

<div *ngIf="(data$ | async) === null">No data</div>
<div *ngIf="(data$ | async)?.length === 0">No data</div>

Template Use Track By Function Rule

Enforces use of trackBy functions with *ngFor for performance.

/**
 * Enforces trackBy functions with *ngFor directives
 * Improves performance by helping Angular track list changes efficiently
 */
export class TemplateUseTrackByFunctionRule extends Lint.Rules.AbstractRule {
  static readonly metadata: Lint.IRuleMetadata;
  static readonly FAILURE_STRING: string;
  apply(sourceFile: ts.SourceFile): Lint.RuleFailure[];
}

Usage Examples:

Good with trackBy:

<div *ngFor="let item of items; trackBy: trackByFn">{{ item.name }}</div>

Component:

trackByFn(index: number, item: any) {
  return item.id;
}

Template Conditional Complexity Rule

Measures and limits conditional complexity in templates.

/**
 * Enforces maximum conditional complexity in Angular templates
 * Promotes readable templates by limiting nested conditionals
 */
export class TemplateConditionalComplexityRule extends Lint.Rules.AbstractRule {
  static readonly metadata: Lint.IRuleMetadata;
  static readonly FAILURE_STRING: string;
  apply(sourceFile: ts.SourceFile): Lint.RuleFailure[];
}

Template Cyclomatic Complexity Rule

Measures cyclomatic complexity in Angular templates.

/**
 * Measures cyclomatic complexity in Angular templates
 * Helps identify overly complex templates that should be refactored
 */
export class TemplateCyclomaticComplexityRule extends Lint.Rules.AbstractRule {
  static readonly metadata: Lint.IRuleMetadata;
  static readonly FAILURE_STRING: string;
  apply(sourceFile: ts.SourceFile): Lint.RuleFailure[];
}

Template I18n Rule

Enforces internationalization attributes for text content.

/**
 * Enforces i18n attributes on elements with text content
 * Ensures application text is properly marked for internationalization
 */
export class TemplateI18nRule extends Lint.Rules.AbstractRule {
  static readonly metadata: Lint.IRuleMetadata;
  static readonly FAILURE_STRING: string;
  apply(sourceFile: ts.SourceFile): Lint.RuleFailure[];
}

Usage Examples:

Good with i18n:

<p i18n="@@welcome.message">Welcome to our application</p>
<button i18n="@@button.save">Save</button>

Template No Autofocus Rule

Prevents use of autofocus attribute for accessibility reasons.

/**
 * Prevents autofocus attribute usage in templates
 * Improves accessibility by avoiding unexpected focus changes
 */
export class TemplateNoAutofocusRule extends Lint.Rules.AbstractRule {
  static readonly metadata: Lint.IRuleMetadata;
  static readonly FAILURE_STRING: string;
  apply(sourceFile: ts.SourceFile): Lint.RuleFailure[];
}

Template No Distracting Elements Rule

Prevents use of distracting HTML elements like <blink> and <marquee>.

/**
 * Prevents use of distracting HTML elements
 * Improves accessibility and user experience
 */
export class TemplateNoDistractingElementsRule extends Lint.Rules.AbstractRule {
  static readonly metadata: Lint.IRuleMetadata;
  static readonly FAILURE_STRING: string;
  apply(sourceFile: ts.SourceFile): Lint.RuleFailure[];
}

Event Handling Rules

Template Click Events Have Key Events Rule

Ensures click events have corresponding keyboard events for accessibility.

/**
 * Ensures click events have corresponding keyboard event handlers
 * Improves accessibility by providing keyboard navigation alternatives
 */
export class TemplateClickEventsHaveKeyEventsRule extends Lint.Rules.AbstractRule {
  static readonly metadata: Lint.IRuleMetadata;
  static readonly FAILURE_STRING: string;
  apply(sourceFile: ts.SourceFile): Lint.RuleFailure[];
}

Usage Examples:

Good with keyboard events:

<div (click)="handleClick()" (keyup.enter)="handleClick()" (keyup.space)="handleClick()">
  Clickable content
</div>

Template Mouse Events Have Key Events Rule

Ensures mouse events have corresponding keyboard alternatives.

/**
 * Ensures mouse events have corresponding keyboard event alternatives
 * Maintains accessibility for keyboard-only users
 */
export class TemplateMouseEventsHaveKeyEventsRule extends Lint.Rules.AbstractRule {
  static readonly metadata: Lint.IRuleMetadata;
  static readonly FAILURE_STRING: string;
  apply(sourceFile: ts.SourceFile): Lint.RuleFailure[];
}

Rule Configuration Options

Example Template Rules Configuration

{
  "rules": {
    "template-banana-in-box": true,
    "template-no-call-expression": true,
    "template-no-any": true,
    "template-no-negated-async": true,
    "template-use-track-by-function": true,
    "template-conditional-complexity": [true, 4],
    "template-cyclomatic-complexity": [true, 5],
    "template-i18n": [true, "check-id", "check-text"],
    "template-no-autofocus": true,
    "template-no-distracting-elements": true,
    "template-click-events-have-key-events": true,
    "template-mouse-events-have-key-events": true
  }
}

Performance Impact

Template rules help identify performance bottlenecks:

  • Function calls in templates trigger on every change detection
  • Missing trackBy functions cause unnecessary DOM updates
  • Complex templates impact rendering performance

Accessibility Benefits

Many template rules enforce accessibility best practices:

  • Keyboard event alternatives for mouse interactions
  • Proper ARIA attributes and roles
  • Avoidance of problematic elements and patterns

Install with Tessl CLI

npx tessl i tessl/npm-codelyzer

docs

accessibility-rules.md

angular-framework.md

component-rules.md

decorator-metadata-rules.md

directive-rules.md

index.md

input-output-rules.md

lifecycle-rules.md

pipe-rules.md

style-architecture-rules.md

template-rules.md

tile.json