0 Tage Serie
javascript / expert
Snippet

Unveränderliche Inputs erzwingen mit Readonly-Signal-Wrappern

Indem der erforderliche Input als ReadonlyArray<CartLine> mit einem CartLine-Interface typisiert wird, dessen Felder alle readonly sind, wird versehentliche In-Place-Mutation zu einem Kompilierfehler statt zu einem Laufzeitfehler — relevant, weil signalbasierte Change Detection Referenzen vergleicht, nicht tiefe Inhalte. Würde ein Kind versehentlich lines().push(...) auf einem gewöhnlichen Array aufrufen, würde Angular die Änderung nie erkennen, da die Array-Referenz gleich bleibt und die UI stillschweigend vom tatsächlichen Warenkorbzustand abweicht. Die Unveränderlichkeit von Array und Elementen zwingt Aufrufer dazu, bei jedem Update stets ein neues Array zu erzeugen — genau das, was computed() zur Neuberechnung veranlasst.

snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { Component, input, computed, Signal } from '@angular/core';
interface CartLine {
readonly sku: string;
readonly qty: number;
readonly price: number;
}
@Component({
selector: 'app-cart-summary',
standalone: true,
template: `<p>Total: {{ total() | currency }}</p>`,
})
export class CartSummaryComponent {
lines = input.required<ReadonlyArray<CartLine>>();
protected readonly total: Signal<number> = computed(() =>
this.lines().reduce((sum, line) => sum + line.qty * line.price, 0)
);
protected readonly isEmpty: Signal<boolean> = computed(
() => this.lines().length === 0
);
}
angular
Erklärung
1
interface CartLine { readonly sku: string; readonly qty: number; readonly price: number; }
Markiert jedes Feld als readonly, sodass TypeScript jeden Codepfad ablehnt, der eine Eigenschaft eines bestehenden Zeilenelements neu zuweist.
2
lines = input.required<ReadonlyArray<CartLine>>();
Typisiert das Input-Signal als schreibgeschütztes Array und blockiert mutierende Array-Methoden wie push oder splice bereits auf Typebene.
3
this.lines().reduce((sum, line) => sum + line.qty * line.price, 0)
computed() läuft nur erneut, wenn das lines()-Signal eine neue Array-Referenz meldet — genau das garantiert Unveränderlichkeit bei jedem echten Update.