Webcafé — Folge 17
Undefined in TypeScript
In Folge 17 beschäftigen wir uns mit dem speziellen Typen "undefined" in TypeScript. Wir versuchen "undefined" so weit wie möglich in unseren Codes zu vermeiden.
Worum geht es?
In Folge 17 beschäftigen wir uns mit dem speziellen Typen "undefined" in TypeScript. Wir versuchen "undefined" so weit wie möglich in unseren Codes zu vermeiden. Dazu erklären wir die Hintergründe, zeigen Alternativen auf und finden Stellen, an denen "undefined" doch notwendig ist.
Das Gespräch, Wort für Wort
Kapitel
2.614 Wörter in 8 Abschnitten. Jede Zeitmarke springt an die passende Stelle im Audio. Automatisch transkribiert und maschinell nachkorrigiert — im Zweifel gilt das Gesprochene.
Intro
0:00–2:26
-
0:00
Hallo, lieber Kay, und herzlich willkommen an alle da draußen zu einer neuen Folge von unserem Webcafé.
-
0:10
Und der Sommer hat Einzug gehalten in Deutschland, nachdem der Sommer ja bisher etwas enttäuschend war und lange Zeit sehr kalt war. Und da haben wir uns immer beschwert, dass es zu frisch ist. Jetzt beschweren wir uns, dass es zu warm ist. Wir haben gerade 32 Grad hier in Köln. Und Kay, ich glaube, bei dir ist es wahrscheinlich nicht kühler. Ja, Tüdelü von mir. Ich muss mir mal neue Begrüßungen ausdenken. Du hast recht. Ich hoffe, das ist jetzt nicht auch eine dieser Folgen, die erst in drei Monaten erscheint, wenn schon die ersten Schneefälle kommen. Aber ja, bitterlich warm, sag ich mal. Inzwischen haben wir ein paar Folgen auf Halde. Von daher denke ich schon, dass es ein bisschen dauert, bis es veröffentlicht wird.
-
0:44
Aber wir gucken mal. Vielleicht ist es ja dann noch warm. Dann ist das jetzt ein kleiner Sprung zurück zu besseren Zeiten, wenn man sich diese Folge in weiß ich nicht wie vielen Wochen anhört und zurückdenkt an den Sommer.
-
0:54
Ja, dann wünscht man sich wahrscheinlich schon wieder, dass es warm ist. Wenn es da nur noch regnet. Ja, Kay, die Hitze hat mich gebrochen. Und ich habe das erste Mal kein Heißgetränk dabei. Ja, das habe ich auch. Ich lasse dir den Vortritt. Danke. Ja, ich dachte, ich könnte heute prahlen, weil ich nämlich auch jetzt dachte, könnte jetzt der Anbeginn einer neuen Ära oder das Ende einer alten Ära sein.
-
1:16
Und ich habe mir tatsächlich jetzt gerade noch auf die Schnelle einen Milchshake gemacht. Oh, schön. Mit tiefgefrorenen Banane. Ja, die Banane war nicht tiefgefroren, aber Erdbeeren und Himbeeren. Dazu einen Schluck Milch und einen ganz kleinen Schluck Agarven-Dixer. Weil wir ja ein bisschen auf den Zucker reduzieren. Super gut. Ja, das hört sich so ein bisschen nach meinem Frühstück an. Ich hatte nämlich so einen Joghurt-Smoothie. Der war auch wunderbar. Jetzt habe ich mir aber mitgebracht einen kalten Tee. Also dem Tee bin ich treu geblieben. Aber das sind diese kalten Tees, die man jetzt in allen Supermärkten findet.
-
1:50
Und das ist so ein Eistee-Piersig. Schmeckt tatsächlich ganz gut. Ich habe so einen Eiswürfel reingeworfen. Der ist aber inzwischen schon längst weg. Und das finde ich ganz lecker. Und erinnere mich so ein bisschen an unsere alten LAN-Party-Zeiten, wo man immer diese anderthalb Liter Tetra Pax Eistee 4 sicherte. Kennst du die noch? Also es ist fertiger Eistee, den du hast, ja? Nein, nein. Also es ist schon ein Teebeutel. Also jetzt heutzutage. Früher war es fertiger, ne? Genau. Also es ist ein Teebeutel, den schmeißt du in kaltes Wasser. Und dann hast du so ein Erfrischungsgetränk. Was es alles gibt.
-
2:16
Wir haben natürlich beide die Chance verpasst, um mal richtigen Eistee aufzusetzen. Mit so grünen Tee aufgekocht und dann im Kühlschrank und so weiter. Ja, das kannst du mal machen, wenn wir im Büro sind. Oh je. Gut, wir kommen mal zur Folge. Und zwar haben wir uns heute wieder einen Brocken vorgenommen. Und ich hoffe, wir haben ihn so ein bisschen runtergebrochen. Denn es geht in vorderster Front um Types. Und da sprechen wir über Types in TypeScript. Und da könnte man natürlich jetzt wahnsinnig viel daraus machen. Deswegen haben wir das erstmal reduziert auf einen bestimmten Type, nämlich undefined.
Einleitung ins Thema
2:26–3:47
-
2:49
Und es geht jetzt weniger darum, zu erklären, welche kuriosen Szenarien man mit undefined erzeugen kann. Also damit kann man ja jeden erfahrenen Programmierer in Coding Challenges zur Verzweiflung bringen. Weil dann doch immer unerwartetes Verhalten irgendwie erzeugt werden kann. Sondern es geht mehr darum, zu gucken, wie wir undefined einsetzen, an welchen Stellen wir es einsetzen, ob wir es einsetzen. Ja, genau. Also wirklich die Praxiserfahrung hier. Genau, das ist passend zum Wetter vielleicht ein etwas überschaubares Thema. Zumindest sind meine Skripte hier nicht so lang. Aber der Aufhänger war auch wieder ein Merge-Request.
-
3:22
Oder beziehungsweise eher generell unsere Coding-Guidelines. Weil wir als Firma gesagt haben, wir wollen undefined im Code nicht verwenden. Und in der Realität kommt dann doch ganz schön häufig undefined war, wenn man mit so einem normalen JavaScript arbeitet. Und damit ich mir nicht künftig immer wieder den Mund fusselig reden muss über dieses Thema, sprechen wir es jetzt hier final im Podcast an.
Was ist "undefined"?
3:47–5:18
-
3:47
Jetzt hast du ja schon ganz viel vorweggenommen, dass wir es eben vermeiden wollen. Aber fangen wir von vorne gerne an. Genau. Also undefined ist eines der Primitives-Types von JavaScript neben Strings und numerischen Werten und Booleans und so weiter.
-
4:04
Und wird von JavaScript hauptsächlich eingesetzt, so als Soft-Error, sag ich mal. Das heißt, JavaScript gibt dir undefined als Antwort, immer wenn du eine Operation ausführst, die nicht so richtig sinnvoll ist.
-
4:17
Also zum Beispiel, wenn du eine Variable definierst, aber ihr noch keinen Wert zuweist. Oder wenn du auf eine Objekteigenschaft zugreifst, die vorher nicht definiert wurde. Oder zum Beispiel auf ein Array mit einem Index, wo es aber zu diesem Index gar keinen Eintrag gibt. Das sind alles Stellen, wo andere Programmiersprachen dir heftig um die Ohren fliegen würden. Und JavaScript löst das so ein bisschen unter der Hand, sag ich mal, indem es dir als Antwort undefined als Value gibt.
-
4:48
Und das ist ein Wert, mit dem du interagieren kannst, wie mit Null oder Null als Integer oder sowas.
-
4:58
Aber irgendwie ist es so ein komischer Zwischenfall. Und unsere Interpretation davon ist, dass undefined schon im Namen steckt. Nämlich, es ist nicht definiert, was hier passieren soll. JavaScript handelt das so ein bisschen locker, aber eigentlich würde es uns damit sagen, hier stimmt irgendwas nicht. Und unsere Interpretation davon ist, wir schreiben keinen undefinierten Code, sondern jede einzelne Zeile definieren wir. Deswegen ist alles, was wir machen, immer definiert. Und undefined ist dann ein Symbol oder eine Stelle, wo wir eben vergessen haben, irgendwelche Fehlerfälle abzudecken, irgendwelche Checks vorab zu machen, irgendwie so Eventualitäten abzufrühstücken.
Wie wir mit "undefined" umgehen
5:18–5:56
-
5:46
Und deswegen haben wir sogar ES in Regeln implementiert, die sagen, man darf undefined nicht aktiv verwenden und muss dann auf andere Sachen zurückgreifen.
Optionale Parameter
5:56–8:08
-
5:56
Jetzt drängt sich bei mir direkt eine Frage auf. Vielleicht greife ich damit aber auch vorweg. Aber wenn ich die einfach mal reinschmeißen darf, das undefined für mich, der klassische Fall ist ja ein optionaler Parameter in einer Funktion. Und wenn der eben nicht gesetzt ist, ist er undefined. Genau. Dürfte ich das machen? Müsste ich das abprüfen? Optionaler Parameter heißt ja, das ist ein Parameter, den du beim Funktionsaufruf füllen kannst oder nicht. Angenommen, du hast eine Funktion mit einem festen Parameter, sag ich es mal, und einem optionalen Parameter.
-
6:28
Dann kannst du diese Funktion entweder mit einem oder mit zwei Parametern aufrufen. Und wenn du sie nur mit einem Parameter aufrufst, dann ist innerhalb der Funktion der zweite Parameter undefined. So funktioniert das im Hintergrund. Und da auch wieder undefined im Sinne von, es wurde nicht definiert, was denn in diesem Fall passieren soll. Und dadurch hat die Anwendung so einen komischen Zustand von, es wurde dieser Fall nicht explizit bedacht. Und um deine Frage zu beantworten, wir benutzen ständig optionale Parameter, insbesondere in React mit verschiedenen Props. Aber was wir dann immer machen, ist, wir setzen einen Default-Wert für den Parameter,
-
7:09
sodass er nicht undefined sein kann, sondern dann irgendwas anderes. Ja, verstehe. Das heißt, im optionalen Parameter damit gleich direkt eine Zuweisung machen. Genau. Ich habe so ein schönes Schaubild bei Stack Overflow gefunden, wo sie Unterscheidung war mit einer Papierrolle. Ich weiß nicht, ob du das auch gefunden hast. Nee. Kann ich vielleicht mal verlinken. Also da gibt es so die vier Möglichkeiten anhand von einer Papierrolle, also Klopapierrolle auf dem Spender. Und alle Non-Zero-Value sind also eine Rolle mit Papier drauf. Null ist eine leere Papierrolle. Null ist ein Spender, wo die Papierrolle fehlt.
-
7:46
Und undefined ist einfach gar kein Spender erst. Und dann nochmal den Unterschied hervorzuheben zwischen Null ist also explizit ein Wert, der absichtlich leer ist, mit vollem Bewusstsein und voller Absicht. Und undefined, das ist eben dieser magische Zwischenraum von JavaScript fliegt dir nicht um die Ohren, aber man weiß auch nicht so richtig, was hier zu tun ist. Und um da mal so ein paar Alternativen zu nennen, was wir stattdessen mit undefined machen, ist üblicherweise eben Null zu setzen, also den JavaScript-Typ Null explizit zu benutzen,
Alternativen zu "undefined"
8:08–10:13
-
8:21
um zu symbolisieren, hier ist etwas absichtlich leer. Hier ist absichtlich ein Parameter nicht da oder sonst irgendwas. Und das bedeutet zum Beispiel auch, wenn man so eine Array-Funktion hat, Array.find gibt es üblicherweise, da sucht man einen Eintrag innerhalb eines Arrays und der gibt standardmäßig undefined zurück, wenn man unter den Kriterien keinen Eintrag gefunden hat, dann immer mit so einem Doppelfragezeichen Null als Default setzen, sodass wir immer explizit sagen, Null ist unser Fallback sozusagen. Eine andere Möglichkeit ist, wo undefined auch häufig verwendet wird, ist, wenn man prüfen möchte, ob ein Objekt eine bestimmte Eigenschaft hat.
-
9:02
Ja, wenn man auf eine Objekteigenschaft zugreift, die nicht da ist, dann ist die automatisch undefined. Und so benutzen Entwickler häufig undefined, um zu checken, hat denn das User-Objekt eine Eigenschaft namens E-Mail oder sowas.
-
9:16
Was unsere Alternative dafür ist, mit Kombination mit TypeScript ist wieder dieses In-Keyword, dass man sagen kann, E-Mail in User-Objekt zum Beispiel. Und dadurch können wir feststellen, ob es diese Eigenschaft generell in dem Objekt gibt. Und dass diese Eigenschaft dann wiederum einen bestimmten Wert hat, haben wir über TypeScript festgelegt. Also das ist vielleicht auch so ein kleiner Trick, mit diesem In-Keyword zu checken, hat ein Objekt eine Eigenschaft, statt auf die Objekteigenschaft zuzugreifen und zu prüfen, dass sie nicht Null ist. Und sich da im Zweifel zu verschreiben und auf eine falsche Eigenschaft zuzugreifen und dann davon auszugehen,
-
9:53
dass sie immer Null ist zum Beispiel oder immer undefined ist. Genau. Natürlich mit modernen IDEs und mit TypeScript sind Typos eher weniger ein Problem. Aber insbesondere, wenn man mit so APIs interagiert, wo man nicht ganz sicher sein kann, ob das so aussieht, wie es wirklich soll, ist das zum Beispiel eine Möglichkeit. Jetzt habe ich schon gesagt, in JavaScript kommt undefined ganz schön häufig vor. Und dementsprechend haben wir auch große Ausnahmen von dieser Regel. Und diese Ausnahmen betreffen insbesondere die Schnittstellen, wo wir mit irgendwelchen anderen Programmbauteilen interagieren, auf die wir keinen Einfluss haben.
Ausnahmen
10:13–14:50
-
10:32
Also was ich damit meine, ist, dass wir bei Funktionen, die wir selber schreiben, natürlich die optionalen Parameter mit so einem Default-Handhaben können und dann Null setzen oder sowas. Aber insbesondere so native JavaScript-Funktionen oder auch, wenn man im React-Kosmos unterwegs ist und dann mit HTML-Elementen interagiert,
-
10:54
da ist es immer wieder so, dass HTML als Standarddefinition für eine leere Eigenschaft undefined haben möchte.
-
11:02
Die akzeptieren kein Null, sondern die möchten undefined. Also Beispiel, ich habe einen Div und möchte dem explizit keinen Style setzen. Dann kann ich dem nicht Null als Style übergeben, sondern muss undefined da reinsetzen, sonst fliegt der uns um die Ohren.
-
11:17
Oder wenn wir mit Material-UI wieder im React-Konsmos interagieren. Die halten sich ja auch sehr nah an die HTML-API und deswegen kommt es da auch immer mal wieder vor, dass wir sagen, hier will das Objekt, das wir benutzen und auf das haben wir keinen Einfluss, undefined als Parameter haben. Und dann müssen wir das natürlich auch setzen. Anders geht es ja dann nicht. Habe ich selbst im Code auch schon öfter erlebt, weil man ja wirklich oft die Situation hat, dass man ein Attribut gar nicht rendern will, sei das schon allein aus Performance-Gründen oder dass der Code ein bisschen aufgeräumter aussieht, der hinterher rausgerendert wird.
-
11:52
Genau, so ein klassisches Beispiel ist auch noch eine On-Click-Funktion auf einem Button, die man unter irgendeiner Bedingung setzen möchte oder nicht. Da kommt man um undefined gar nicht herum. Und was wir dann dafür gemacht haben, ist, so eine explizite Konstante zu setzen, die wir irgendwo im Code definiert haben, auch mit entsprechenden ES-Lint-Tags, dass sich der nicht beschwert. Und dann setzen wir überall da, wo es nötig ist, eben undefined alternativ dazu ein über diese Konstante, sodass man auch wirklich sieht, das habe ich absichtlich hier an dieser Stelle gemacht, weil es wirklich nicht anders geht, weil ich mit irgendeiner Drittanbieter-API zu tun habe.
-
12:29
Auch wichtig an der Stelle, wirklich erst da, wo es gar nicht mehr anders geht. Also nicht schon irgendwo im Code vorher undefined setzen, weil ich weiß, dass ich es irgendwo fünf Zeilen weiter in irgendeiner API einsetze, die ich nicht kontrollieren kann. Also klassisches Beispiel ist eine React-Komponente, wo man unten diesen On-Click-Listener übergeben will. Dann mache ich nicht oben schon im React-Body oder in den React-Parametern undefined, weil ich weiß, dass ich es unten brauche, sondern wirklich erst in der Zeile HTML unten, wo es wirklich nicht mehr anders geht. Das sorgt eben dafür, dass man undefined in der Bedeutung auch aus dem Code verbannt.
-
13:08
Das bedeutet, wir haben alles definiert. Dementsprechend gibt es kein undefined. Und es kann dann sehr gut als so Debugging-Mechanismus helfen, weil wenn dann wirklich irgendwo undefined bei rauskommt, dann wissen wir, okay, hier ist eine Stelle, die wurde nicht ausführlich genug bedacht. Das führt aber leider dazu, dass man manchmal auch so extra Krücken dreht, wo man sich denkt, ist das jetzt wirklich nötig gewesen? Weil man dann irgendwo in der Zeile so eine native Array-Funktion benutzt, sag ich mal. Da kommt dann undefined raus als Standard-Default. Das überschreiben wir dann explizit mit Null.
-
13:45
Nur um zwei Zeilen unter, weil es dann an eine HTML-Komponente übergeben wird, das Null wieder zu überschreiben mit undefined, wo man sagt, ja, wenn ich es da oben gleich undefined lasse, hätte ich es da unten direkt einsetzen können. Aber unsere Herangehensweise ist, lieber Zeile für Zeile gutschreiben und dann sieht man diesen Zusammenhang nicht und dann muss man vielleicht mal diesen Umweg gehen, als dass man sich so Krücken einbaut und das wird dann so aufgeweicht. Ist aber am Ende eine gefährliche Gratwanderung, dass man sich den Code damit auch nicht überkompliziert und da nicht zu sehr von dem abweicht, was andere machen.
-
14:18
Genau, insbesondere weil das eben so eine verbreitete Syntax in nativen HTML ist, gibt es sehr viele Bibliotheken, die so sehr DOM-nah sind, die mit diesem undefined auch arbeiten. Und da sieht man immer wieder in den Dokus und Beispielen, wie damit undefined gearbeitet wird. Und das ist dann häufig für Neuentwickler bei uns ein kleiner Stolperstein. Deswegen jetzt auch diesen Podcast hier. Also das in aller Kürze zum Thema, warum wir undefined doof finden und wie wir es möglicherweise anders lösen können in den verschiedenen Stellen. Wunderbar, also nehmen wir als Take mal da raus. Wir wollen undefined bei uns zumindest und es hat sich bei uns ja sehr bewährt,
Zusammenfassung
14:50–15:32
-
14:58
möglichst vermeiden. Es gibt trotzdem Stellen, wo wir undefined nutzen wollen. Als gutes Beispiel hast du genannt diese HTML-Attribute, die man mit undefined als einzige Option dann tatsächlich komplett unterdrücken kann. Ansonsten muss man sich eben gut überlegen, an welchen Stellen man undefined dann einsetzen will, damit es nicht zu anderen Problemen kommt an anderer Stelle dann. Genau, das Stichwort ist gut überlegen, also undefined bewusst einsetzen im Code und nicht so als Standard hinnehmen, weil JavaScript das einfach so macht. Ich glaube, dann lassen wir die Folge tatsächlich heute so kurz stehen.
-
15:30
Fantastisch, hitzefrei. Genau, dann bleibt mir nämlich noch eine Sekunde, um daran zu erinnern, dass ihr uns gerne ein Like da lassen dürft, dass ihr gerne unseren Podcast abonnieren dürft und wenn ihr sogar die Zeit dazu findet, bewertet auch gerne auf den bekannten Plattformen. Fantastisch, Felix. Ich freue mich aufs nächste Mal. Kay, wir hören uns ja in der nächsten Woche. Bis dahin.
Nebenan im Webcafé
Alle zwei Wochen montags eine neue Folge über Webentwicklung, Codequalität und die Art, wie wir zusammenarbeiten.
Alle 52 FolgenFragen an Felix und Kay?
Themenwunsch, Widerspruch oder eine Frage aus Deinem Projektalltag — schreib uns. Was uns erreicht, landet regelmäßig in einer der nächsten Folgen.
podcast [at] geenen-it-systeme.de
