Générez le code TypeScript des Angular Signals : signal, computed, effect, input, model, output, toSignal et resource, en snippet, composant ou service.
Générateur Angular Signals
🔧 Configuration
Angular Signals : la nouvelle réactivité d'Angular
Les Signals sont le système de réactivité fine introduit dans Angular 16 et stabilisé depuis Angular 17. Un signal est un conteneur de valeur qui notifie automatiquement Angular quand son contenu change — ce qui permet une détection de changements ciblée, sans Zone.js, et un code plus simple et plus performant. Ce générateur produit le code TypeScript correct pour chaque primitive : signal, computed, linkedSignal, effect, input, model, output, toSignal, toObservable et resource, avec les imports adaptés.
Choisissez l'onglet Extrait pour une déclaration isolée, Composant standalone pour un composant complet prêt à coller, ou Service pour un store de state réactif. Le générateur gère automatiquement les imports depuis @angular/core et @angular/core/rxjs-interop.
signal() — l'état modifiable
Un signal en écriture stocke une valeur et expose trois méthodes : on le lit en l'appelant comme une fonction, on le remplace avec set() et on le modifie à partir de l'ancienne valeur avec update().
import { signal } from '@angular/core';
export class CounterComponent {
count = signal<number>(0);
increment() {
this.count.update(v => v + 1); // à partir de la valeur précédente
}
reset() {
this.count.set(0); // remplace directement
}
}
// Template : <p>{{ count() }}</p> ← lecture par appel de fonction
computed() — les valeurs dérivées
computed() crée un signal en lecture seule dont la valeur est recalculée automatiquement dès qu'un signal lu à l'intérieur change. Le calcul est mémoïsé : il ne s'exécute que si une dépendance a réellement changé.
import { signal, computed } from '@angular/core';
price = signal(100);
quantity = signal(2);
total = computed(() => this.price() * this.quantity()); // recalculé auto
totalTTC = computed(() => this.total() * 1.2); // dépend d'un autre computed
computed(). Un computed doit être une fonction pure qui se contente de dériver une valeur — les effets de bord vont dans effect().
effect() — les effets de bord réactifs
effect() exécute du code à chaque fois qu'un des signaux lus à l'intérieur change. C'est l'endroit pour logger, synchroniser avec le localStorage, ou déclencher une action externe. Un effect se déclare dans un contexte d'injection (constructeur ou champ d'initialisation).
import { signal, effect } from '@angular/core';
export class ThemeComponent {
theme = signal<'light' | 'dark'>('light');
constructor() {
effect(() => {
// s'exécute à chaque changement de this.theme()
localStorage.setItem('theme', this.theme());
document.body.dataset['theme'] = this.theme();
});
}
}
input(), model() et output() — les API de composant
Depuis Angular 17.1, les entrées/sorties de composant s'écrivent aussi sous forme de signaux, remplaçant les décorateurs @Input() et @Output().
| API | Remplace | Usage |
|---|---|---|
input() |
@Input() |
Entrée en lecture seule, avec input.required() pour l'imposer |
model() |
@Input() + @Output() |
Liaison bidirectionnelle [(value)] |
output() |
@Output() + EventEmitter |
Émission d'événement via .emit() |
import { input, model, output } from '@angular/core';
export class UserCardComponent {
userId = input.required<number>(); // obligatoire
size = input<'sm' | 'lg'>('sm'); // optionnel avec défaut
name = model<string>(''); // bidirectionnel [(name)]
deleted = output<number>(); // (deleted)="..."
remove() { this.deleted.emit(this.userId()); }
}
toSignal(), toObservable() et resource() — RxJS et async
Les Signals ne remplacent pas RxJS : ils le complètent. toSignal() convertit un Observable en signal (avec désabonnement automatique), toObservable() fait l'inverse, et resource() (Angular 19+) charge des données asynchrones en exposant value(), isLoading() et error() comme signaux.
import { signal, resource } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
// Observable HTTP → signal
data = toSignal(this.http.get<User[]>('/api/users'), { initialValue: [] });
// Chargement réactif basé sur un signal de requête
userId = signal(1);
userResource = resource({
request: () => ({ id: this.userId() }),
loader: ({ request }) =>
fetch(`/api/users/${request.id}`).then(r => r.json() as Promise<User>)
});
// Template : @if (userResource.isLoading()) { Chargement… }
toSignal() pour l'afficher facilement dans le template, sans pipe async.
FAQ — Angular Signals
signal() est modifiable via set() et update(). computed() est en lecture seule : sa valeur est dérivée d'autres signaux et recalculée automatiquement (et mémoïsée) quand l'une de ses dépendances change.
this.count(). C'est cet appel qui enregistre la dépendance et déclenche la réactivité. Dans le template : {{ count() }}.
signal, computed et effect sont disponibles depuis Angular 16 et stables depuis Angular 17. input()/output() arrivent en 17.1/17.3, model() en 17.2, et linkedSignal() / resource() en Angular 19 (encore expérimentaux).
toSignal() et toObservable() du package @angular/core/rxjs-interop.
Conclusion
Les Signals modernisent profondément la réactivité d'Angular : code plus lisible, détection de changements plus fine, et chemin vers le mode zoneless. Ce générateur vous fait gagner du temps en produisant un code TypeScript correct et idiomatique pour chaque primitive — de la simple variable d'état au chargement asynchrone avec resource(). Copiez l'extrait, le composant ou le service, puis adaptez-le à votre domaine métier.
Pour approfondir, consultez le guide officiel des Signals Angular et combinez cet outil avec notre testeur d'opérateurs RxJS pour maîtriser la réactivité de bout en bout.