Aller au contenu
rdlabo.devdocs

signal-use-as-signal

Ce plugin vérifie que les Signals sont utilisés comme des Signals.

Les Signals Angular sont des fonctions de lecture. Leur lecture exige () et leur écriture doit passer par .set() ou .update(). Cette règle détecte le code qui traite une variable Signal comme une valeur ordinaire et peut corriger automatiquement de nombreuses erreurs courantes.

Détails de la règle

La règle suit les propriétés de classe initialisées avec des fabriques de Signal (signal, model, input, linkedSignal, toSignal, asReadonly) et signale les mauvais usages comme :

  • this.count au lieu de this.count() dans un contexte d’expression
  • this.count() = value au lieu de this.count.set(value)
  • this.user().name = 'Jane' au lieu de this.user.update(user => ({ ...user, name: 'Jane' }))
  • this.items().push(x) au lieu de this.items.update(items => { items.push(x); return items; })
  • this.#user = value (affectation directe à une propriété Signal) au lieu de this.#user.set(value)

La règle distingue les contextes qui attendent une référence de Signal de ceux qui attendent sa valeur. Par exemple, passer un objet Signal comme prop est autorisé :

const props = { food: this.food };
launchModal({ food: this.food });

Exemples

Incorrect

export class SigninPage {
  readonly #id = signal<number | undefined>(undefined);

  constructor() {
    this.#id = 1;
  }

  useMethod() {
    if (this.#id) {
      this.#id().hoge = 1;
    }
  }
}
export class SigninPage {
  readonly #user = signal<{ name: string }>({ name: 'John' });

  updateUser() {
    this.#user().name = 'Jane';
  }
}
export class SigninPage {
  readonly #numbers = signal<number[]>([1, 2, 3]);

  updateNumbers() {
    this.#numbers().push(4);
  }
}
export class SigninPage {
  readonly #value = signal<number>(0);

  updateValue() {
    this.#value() = 42;
  }
}

Correct

export class SigninPage {
  readonly #user = signal<{ name: string }>({ name: 'John' });

  updateUser() {
    this.#user.update((user) => ({ ...user, name: 'Jane' }));
  }
}
export class SigninPage {
  readonly #numbers = signal<number[]>([1, 2, 3]);

  updateNumbers() {
    this.#numbers.update((numbers) => {
      numbers.push(4);
      return numbers;
    });
  }
}
export class SigninPage {
  readonly #value = signal<number>(0);

  updateValue() {
    this.#value.set(42);
  }
}
export class SigninPage {
  readonly food = signal<number>(0);

  openPreview() {
    const props = { food: this.food };
    launchModal({ food: this.food });
  }
}

Correction automatique

La règle propose une correction automatique pour les motifs ci-dessus :

  • this.count = value -> this.count.set(value)
  • this.count() = value -> this.count.set(value)
  • this.count().x = value -> this.count.update(value => ({ ...value, x: value }))
  • this.count().push(x) -> this.count.update(value => { value.push(x); return value; })

Options

Cette règle n’a pas d’options.

Quand l’activer

Activez cette règle dans tout projet Angular utilisant des Signals. Elle complète @rdlabo/rules/signal-use-as-signal-template, qui vérifie l’usage des Signals dans les modèles.

Voir aussi

Implémentation