or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

accessibility-rules.mdangular-framework.mdcomponent-rules.mddecorator-metadata-rules.mddirective-rules.mdindex.mdinput-output-rules.mdlifecycle-rules.mdpipe-rules.mdstyle-architecture-rules.mdtemplate-rules.md
tile.json

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