Signatur
Beschreibung
formatToParts() arbeitet wie Intl.ListFormat.prototype.format(), gibt aber keinen fertigen String zurück. Stattdessen erhältst du ein Array von Objekten, die jeweils ein Stück der formatierten Liste darstellen. Jedes Objekt hat die Eigenschaften type und value. type ist entweder "element" (ein Eintrag aus der Eingabeliste) oder "literal" (ein sprachabhängiges Trenn- oder Verbindungsstück wie ", " oder " und ").
Die Methode ist praktisch, wenn du die Listeneinträge anders darstellen willst als die Trennwörter, zum Beispiel Namen fett oder als Links, während Komma und „und“ normaler Text bleiben. Weil die Literale aus den Lokalisierungsdaten der Laufzeitumgebung kommen, bleiben Reihenfolge und Grammatik in jeder Sprache korrekt. Du musst also keine eigenen Trennregeln pro Sprache schreiben.
Wenn du alle value-Teile in ihrer Reihenfolge zusammenfügst, erhältst du genau den String, den format() mit derselben Eingabe liefern würde. Wie die Liste formatiert wird, legst du im Konstruktor new Intl.ListFormat(locales, options) über type ("conjunction", "disjunction", "unit") und style ("long", "short", "narrow") fest.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $list Pflicht | Iterable<string> | Ein iterierbares Objekt, etwa ein Array oder ein Set, dessen Einträge alle Strings sein müssen. Ohne Argument wird eine leere Liste angenommen. |
Rückgabewert
type: "element" steht für einen Eintrag der Eingabeliste, type: "literal" für einen sprachabhängigen Trenner. Bei einer leeren Liste ist das Array leer.Beispiele
Bestandteile einer deutschen Aufzählung
const lf = new Intl.ListFormat('de', { style: 'long', type: 'conjunction' });
const parts = lf.formatToParts(['Äpfel', 'Birnen', 'Kirschen']);
console.log(parts);
Listeneinträge im DOM hervorheben (XSS-sicher)
const lf = new Intl.ListFormat('de', { type: 'conjunction' });
const names = ['Anna', 'Ben', 'Clara'];
const target = document.querySelector('#teilnehmer');
target.replaceChildren(
...lf.formatToParts(names).map(({ type, value }) => {
if (type === 'element') {
const strong = document.createElement('strong');
strong.textContent = value;
return strong;
}
return document.createTextNode(value);
})
);
// Ergebnis im DOM: <strong>Anna</strong>, <strong>Ben</strong> und <strong>Clara</strong>
Oder-Liste in verschiedenen Sprachen
const options = ['Kreditkarte', 'PayPal', 'Rechnung'];
for (const locale of ['de', 'en', 'es']) {
const lf = new Intl.ListFormat(locale, { type: 'disjunction' });
const literals = lf.formatToParts(options)
.filter((p) => p.type === 'literal')
.map((p) => JSON.stringify(p.value));
console.log(locale, literals.join(' | '));
}
Rekonstruktion entspricht format()
const lf = new Intl.ListFormat('en', { style: 'short', type: 'unit' });
const list = new Set(['5 kg', '3 m', '2 s']);
const joined = lf.formatToParts(list).map((p) => p.value).join('');
console.log(joined === lf.format(list), joined);
// Wichtig · Fallstricke
- Nur Strings erlaubt: Enthält die Liste einen Wert, der kein String ist (z. B. eine Zahl), wird ein
TypeErrorgeworfen. Wandle solche Werte vorher um, etwa mitlist.map(String)oder besser mitIntl.NumberFormat. - Literale können sich ändern: Die Trenner stammen aus den CLDR-Daten der jeweiligen Laufzeitumgebung und können sich zwischen Browsern und Versionen unterscheiden, etwa beim Oxford-Komma im Englischen oder bei Sonderformen wie spanisch „e“ statt „y“. Vergleiche
value-Werte in Tests deshalb nicht fest mit erwarteten Literalen. - Sicherheit: Die Teile sind reiner Text. Wenn du sie mit
innerHTMLin HTML einfügst, entsteht eine XSS-Lücke, sobald die Einträge Benutzereingaben enthalten. NutzetextContentbzw.createTextNode. - Kompatibilität: Unterstützt seit Chrome 72, Firefox 78, Safari 14.1 und Node.js 12.9 (mit vollständigen ICU-Daten). In älteren Umgebungen brauchst du ein Polyfill, z. B.
@formatjs/intl-listformat.