Grundidee
Viele JS/TS-Entwickler*innen sind schonmal über ein Tagged Template Literal gestolpert. Es sieht einem Template Literal bzw. Template String sehr ähnlich (siehe Beispiele unten) – mit dem Unterschied, dass kurz vor dem öffnenden ` ein Funktionsname steht. Doch was genau geschieht hier eigentlich und wie kann man sein eigenes Tagged Template Literal erstellen?
Ein Tagged Template Literal ist prinzipiell eine Funktion, die als ersten Parameter eine Liste aller String-Schnipsel erhält, die beim Aufruf angewandt wurden. Die weiteren Parameter sind die Werte, also das, was via ${...} übergeben wurde. Im Beispiel unten sieht man, wie der Aufruf des Tagged Template Literals css hier sinngemäß zu deuten ist.
Die Funktion kann nun diese Parameter nutzen, um den Rückgabewert zu berechnen.
const styles = `
display: ${display};
color: ${color};
`;
const styles = css`
display: ${display};
color: ${color};
`;
const styles = css([
"\n display: ",
";\n color: ",
";\n"
], display, color);
Praxisbeispiel
Wir wollen uns mal einen Beispielfall anschauen, bei dem man so etwas verwenden könnte. Das Problembeispiel unten zeigt ein Szenario, in dem Daten ausgegeben werden sollen. Doch hier wird leider nicht das ausgegeben, was wir uns erhofft hatten: "My value is [object Object]". Mit einem Tagged Template Literal könnten wir dies jedoch sinnvoll gestalten, siehe im Lösungsbeispiel.
const a = { hello: "world" };
console.log(`My value is: ${a}`);
function readable(
strings: TemplateStringsArray,
...values: unknown[]
) {
return strings
.map((s, i) =>
(i === strings.length - 1)
? s
: `${s}${JSON.stringify(values[i])}`
).join('');
}
const a = { hello: "world" };
console.log(readable`My value is: ${a}`);
Kurze Erklärung dazu:
- strings ist vom Typ TemplateStringsArray. Für die wichtigsten Operationen kann man es jedoch wie einen String-Array ansehen.
- values habe ich hier als unknown typisiert. Dies kann man jedoch klarer spezifizieren und damit sogar Typsicherheit erhalten.
- In der Mapping-Funktion wird beim letzten Element nur der String zurückgeliefert, da ein Wert für den Index nicht existiert.
- Values werden immer von Strings umgeben, und sei es nur ein Empty-String.
- Es gibt also exakt einen String mehr als Werte.
- Die Werte aus dem values Array kann man natürlich dynamisch auswerten. z. B. auch Funktionen erlauben, die dann aufgerufen werden, um den finalen Wert zu erhalten.
- Es muss nicht zwingend ein String zurückgegeben werden. Möglich wäre z. B. auch, eine Funktion zurückzugeben, die das Ergebnis erst bei Bedarf berechnet.
Erwähnenswert: Die IDE kann für solche Tags spezielles Syntax-Highlighting und Code-Completion bereitstellen.
Weitere Aspekte
---
Autor: Santo Pfingsten / Senior Software Architect / Remotee
Lust, das nächste ToiletPaper zu schreiben? Jetzt bei jambit bewerben!