TypeScript - Endlich sauberer Code im Frontend
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 95 | |
Author | ||
License | CC Attribution 4.0 International: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor. | |
Identifiers | 10.5446/32319 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
| |
Keywords |
FrOSCon 201728 / 95
4
8
9
15
20
22
23
24
25
27
29
32
36
37
38
39
40
45
46
47
48
49
50
51
53
54
59
63
64
65
74
75
76
79
83
84
86
87
88
89
91
92
93
94
95
00:00
CodeJavaScriptFocus (optics)MicrosoftBruchteilDatabaseVideo game consoleServer (computing)Software developerComputing platformData typeXMLComputer animationLecture/Conference
02:00
JavaScriptQuery languageCodeEncapsulation (object-oriented programming)jQueryString (computer science)Physical quantityXMLLecture/Conference
03:17
Equals signJavaScriptData conversionElement (mathematics)String (computer science)Binary multiplierXML
04:31
CodeBerechnungComputer animationSource code
05:39
CodeWeb browserMicrosoftElectronic visual displayClient (computing)BarcodesVideo game consolePatch (Unix)JavaScriptComputer animationXML
06:33
Run-time systemKlassenbibliothekJavaScriptDialectEckeCompilerLaufzeitFirefox <Programm>Web browserElectronic signatureSocial classObject-oriented programmingListe <Informatik>Scripting languageVirtual machineImplementationVersion <Informatik>CodeNoten <Programm>Variable (mathematics)ZahlFocus (optics)APILecture/Conference
11:46
CodeVariable (mathematics)Validity (statistics)JavaScriptString (computer science)CompilerData typeHASKELLSocial classParameter (computer programming)Hausdorff spaceLaufzeitBlock (periodic table)Abstract syntax treeXML
18:48
Object-oriented programmingComputer programmingData typeSocial classSharp <Marke>Liste <Informatik>CodeInstanz <Informatik>Parameter (computer programming)String (computer science)NamespaceConstructor (object-oriented programming)CompilerVariable (mathematics)Function (mathematics)Pointer (computer programming)WritingC sharpXMLUML
25:50
JavaScriptData typeConstructor (object-oriented programming)Mobile appOperator overloadingXMLComputer animation
27:11
Statement (computer science)String (computer science)CompilerAttribute grammarNoten <Programm>Block (periodic table)Data typeMISSVersion <Informatik>Variable (mathematics)JavaScriptRoundingVirtual machineParameter (computer programming)Achse <Mathematik>ZahlTwin primeAMBERStaff (military)ImplementationLecture/Conference
30:52
Block (periodic table)Instanz <Informatik>Variable (mathematics)Statement (computer science)CodeJavaScriptError messageBerechnungParameter (computer programming)EditorObject-oriented programmingWeb browserGrand Unified TheoryRaum <Mathematik>Version <Informatik>ZahlNumberFunction (mathematics)ZugriffScope <Programmierung>CapturingXMLUML
37:32
String (computer science)CodeVariable (mathematics)Data typeJavaScriptGreatest elementCompilerComputer programmingAdditionKontrollflussRun time (program lifecycle phase)RollbewegungContent (media)TouchscreenWhiteboardMathematicianInstanz <Informatik>ExplosionswelleObject-oriented programmingSocial classSound <Multimedia>Computer fileAMBERComputer animation
46:52
String (computer science)CASTComputer animation
47:45
CodeData typeLevel (video gaming)Object-oriented programmingServer (computing)Computer programmingCompilerGeneric programmingOrbitMetreGenerating functionString (computer science)Plug-in (computing)XMLComputer animation
53:55
CodeLaufzeitInstanz <Informatik>Object-oriented programmingComputer filePlug-in (computing)EditorFile viewerJavaScriptOperating systemDirection (geometry)Standard deviationHTMLGrand Unified TheorySocial classNoten <Programm>Bookmark (World Wide Web)MicrosoftComputer programmingPlot (narrative)Systems <München>Plane (geometry)Module (mathematics)Moment (mathematics)WEBData typeCompilerLINUXJSONXMLUML
58:44
Run-time systemZahlEditorProduct (category theory)JavaScriptSoftwareTOMCodeVersion <Informatik>CompilerSource codeData bufferLecture/Conference
01:02:28
Computer animation
Transcript: German(auto-generated)
00:07
Guten Morgen zusammen. Man versteht mich vernünftig, hoffe ich, übers Mikrofon. Wunderbar. Mein Name ist Roman Rohlofsson. Willkommen zum Vortrag über TypeScript. Schon mal vorweg, ich bin seit 18 Jahren Linux-User Fulltime.
00:20
Und TypeScript ist eine Technologie von Microsoft. Ich hätte mir im Leben nicht geträumt, dass ich mal auf einer Frostcon eine Microsoft-Technologie vorstelle, aber naja, so kommt's dann. Aber keine Sorge, Happy End, nichts Böses. Ich bin kein Microsoft-Fan, aber das ist wirklich eine schöne Technologie. Das ist eine Einführung in TypeScript. Ich setze nichts voraus, kein Wissen,
00:40
außer vielleicht eine Abneigung gegenüber JavaScript. Die sind in der Regel gut vorhanden. Ich setze mich durch die Folien, dass es viel mehr Stoff, als man in einer Stunde zeigen könnte. Ich habe einfach eine Auswahl von Sprachfeatures, wo ich denke, die machen erst mal sowieso Sinn oder das sind die interessantesten. Es gibt aber keinen Grund, das ganze Lineal so durchzuziehen. Also ich plane keine Zeit am Ende
01:03
für Fragen ein. Unterwegs immer die Hand hoch. Ich kann jederzeit auf eine Konsole wechseln, was tippen, habe ich sowieso eingeplant und einfach so wie Fragen aufpoppen, direkt Bescheid sagen. Und letztlich schaffen in 60 Minuten das, was wir schaffen. Und ist eh nur ein Bruchteil von dem, was man alles zeigen möchte.
01:23
Kurz über mich. Ich bin Geschäftsführer bei der W11K GmbH. Wir sitzen in der Nähe von Stuttgart bei Esslingen und haben noch ein Außenbüro in Siegburg, hier direkt in die Nachbarschaft, in der Nachbarstadt. Manche kennen vielleicht The Code Campus, eine Schulungsplattform von uns. Da bieten wir Angular und TypeScript Schulungen an. Und letztlich, was wir so Fulltime machen, ist Webentwicklungen
01:43
mit einem Fokus auf Frontend. Also Server gehört dazu, aber mehr so, weil man irgendwie in die Datenbank muss. Letztlich tun wir uns im Frontend aus. Sind aber auch keine Pixelschubser. Also dafür brauchen wir auch nochmal andere Designer. Okay, warum sind wir hier? JavaScript, habe ich schon gesagt, eine Abneigung ist immer gut,
02:00
wenn die da ist. Der Erfinder von TypeScript, ich habe den Namen gerade vergessen, ist übrigens der gleiche, der C-Sharp gemacht hat und Delphi. Ich weiß nicht, weiß es jemand zufällig den Namen? Ja, gut. Der hat gesagt, JavaScript skaliert nicht. Und was er letztlich damit meinte, es skaliert weder für größere Teams, also wenn man nicht alleine ist, und es skaliert nicht für größere Projekte. Also je größer die Codebasis, desto schwieriger wird es
02:25
mit JavaScript das Ganze zu erwarten. Das ist ein Problem. Ich denke, das kann jeder bestätigen, der mal versucht hat, in JavaScript etwas Größeres aufzuziehen, was über einen jQuery Nutzung hinausgeht. Dann gehört er sicherlich dazu, aber das war so der Haupt-Painpoint,
02:42
auch den wir gemerkt haben. Die Möglichkeit zur Kapselung in JavaScript basiert letztlich auf Convention. Man einigt sich auf ein gewisses Verhalten, wie man den Code strukturiert. Es gibt dann die einzige technische Möglichkeit, dass man Sachen in so Funktionen versteckt. Immediately invoked Functions. Aber ansonsten kennt JavaScript keine Granularität auf
03:03
Dateiebene, auf Ordnerebene, auf Klassebene, was auch immer. Und hier so ein paar Beispiele, fragwürdiges Verhalten. Der erste ist immer so der größte Schocker, wenn man also ich vergleiche hier ein String und ein Number mit dem Gleichgleich, wie man das
03:20
jetzt aus Java zum Beispiel kennt. Und das würde mir hier true liefern. Das heißt, der macht automatisch implizit eine Konvertierung. In dem Fall von dem String 1 auf die Number 1. Das ist der Grund, warum es die zweite Zeile gibt. Deswegen würde man so in JavaScript nie vergleichen, sondern das mit den drei Gleichheitszeichen machen.
03:40
In der Regel wundern sich immer ein paar und sagen, ach, deswegen gibt es das. Da ist es wie erwartet. Deswegen, zweite Zeile, das würde ich kein fragwürdiges Verhalten. Das ist so, wie man es haben möchte. Zeile 3, auch ein gutes Beispiel. Ich kann String und Number multiplizieren. Würde auch implizit konvertieren. Es ist nur ein kleiner Ausdruck. Und das Schönste ist, die letzte Zeile der JavaScript Batman. Hat jemand eine Idee, was dabei rauskommt? Ich gebe euch 10
04:04
Sekunden zum grübeln. Also Array 16 bedeutet, mach ein leeres Array mit 16, leeren Elementen. Verknüpfe die dann mit dem String A-1, was auch immer dabei rauskommt. Und dann die Batman. Du wolltest schon was sagen. Genau. Es ist so
04:23
schön, es nicht zu zeigen. Deswegen kopiere ich es einmal. Das ist hier mein TypeScript schon. Und er ist jetzt ein bisschen zu schlau. Deswegen muss ich ihn gerade mal eben ärgern. Dann mache ich es direkt hier unten.
04:52
Kann man das lesen? Das Schöne ist, dass A-1 liefert keine Exception, wie das eine vernünftige Sprache machen würde. Sondern der Rückgabewert ist
05:00
not a number. Und das dann 16 mal gibt einen schönen Batman-Intro. Können wir alle singen. Das Schlimme an diesem not a number ist, wenn ich jetzt mal sage, A ist eben dieser Mist. Also A ist jetzt hier not a number. Ich kann damit natürlich weiter rechnen und alles Mögliche
05:21
machen. Ich würde nie eine Exception kriegen. Es zieht sich einfach not a number durch meinen Code. Und das Schlimme ist, das kann ja durch 20 Methoden-Aufrufe gehen. Und ganz am Ende sehe ich not a number. Ich habe aber keine Ahnung, wo unterwegs ist, da die Berechnung nicht geklappt hat. Also ein schönes Beispiel, warum das Ganze logischerweise für größeren Code nicht so skaliert. Also auch so zum Live-Coding.
05:44
Ich würde immer hier was tippen. Wechsel dann einmal den Bildschirm in den Browser. Und das, was wir dann da unten sehen, ist wenn das zu schnell geht, immer direkt Bescheid sagen. Manchmal bin ich ein bisschen zu hektisch. Okay, das nur das kleine Teaser,
06:01
warum JavaScript so blöd ist. Deswegen TypeScript. Wie schon angedroht, das Ganze wurde von Microsoft entwickelt. Oder wird. Als das rauskam, habe ich so gedacht, eh blöd, bestimmt eine Exe-Datei, kann ich nicht so anfangen, schaue ich mir gar nicht an. Aber siehe da, das Ganze basiert auf der Apache-Lizenz. Ist gut. Und wird auch öffentlich
06:21
transparent auf GitHub entwickelt. Ganz am Anfang lag das bei Codeplex, das war von Microsoft, deren Code-Community-Plattform, wie auch immer. Ich glaube, die haben die komplett eingestampft und alles zu GitHub migriert. Angeblich ist Microsoft der größte Committer, wahrscheinlich weil sie ihre ganzen Teams nochmal nach GitHub migriert haben. Auf jeden Fall alles transparent da. Apache-Lizenz. Und das Ganze ist in JavaScript geschrieben
06:44
und läuft als Node-Umgebung. Also auf jedem Betriebssystem, wo Node läuft, läuft auch TypeScript. Wobei, braucht ja nicht mal ein TypeScript-Code. Das Ganze ist ein Compiler, der den TypeScript-Code nimmt, den wir eintippen, und der spuckt uns JavaScript-Code aus.
07:03
Das wird sich dann Transpiler nennen. Also das hier. Letztlich ein Compiler, der Source-Code generiert und dann nennt man es Transpiler. Macht doch Sinn, JavaScript selber kennt ja keinen Binär-Format oder Byte-Format. Das ist quasi JavaScript-Code. Entsprechend ist das das, was generiert wird. Es gab immer
07:22
das Ziel, dass der generierte JavaScript-Code möglichst nah an dem ursprünglichen TypeScript-Code ist. Also dass der im Rahmen der Möglichkeiten immer noch lesbar ist. Das wird natürlich umso mehr aufgeweicht, umso mehr komplexere Features wir von TypeScript nutzen. Grundsätzlich ist der Anspruch aber noch da. Also es ist kein
07:42
obskurer Code, den man nicht lesen kann, wo die Benamungen auf einmal anders sind. Wenn die Variable bei uns in TypeScript A heißt, heißt sie auch in JavaScript nach A. Ist natürlich auch wichtig für Interoperabilität mit anderen Bibliotheken, JavaScript-Code etc. Dann, das fand ich sehr gut, das neue Sprachen für bestehende Sprachen entwickeln,
08:03
kennt die Branche jetzt ja schon länger, besonders im Java-Umfeld. Weiß nicht, woher das herkommt, aber in der Regel hat auch was mit Java so ein bisschen zu tun. Und die bringen auch immer eine eigene API mit. Die sagen also nicht nur, wir haben eine bessere Syntax, wir haben auch eine bessere Klassenbibliothek. Wir haben andere Collection-Klassen, andere Listen, alle Objekte. Und das fand ich immer ein
08:20
bisschen blöd, weil jede neue Klasse ist erstmal per Definition incompatibel zu einer anderen Klasse. Es ist ja eine neue API, eine neue Signatur. Und gleichzeitig gibt es aber Bibliotheken in JavaScript, wie zum Beispiel Lodash oder in Java ein Guava, wo ich immer gedacht habe, wäre doch viel schöner, wenn man das einfach ein bisschen trennen würde. So ist es hier auch gemacht.
08:41
Das Ganze ist nur ein Compiler. Es gibt keine Laufzeitumgebung, es gibt keine API. Das heißt, es bezieht sich nur auf die Syntax, die ich eintippe. Und zur Laufzeit binde ich ein Lodash, ein Underscore, ein JQuery, was auch immer ein, so wie ich es brauche. Hält den Fokus natürlich auch schön. Ja, gut ausgerichtet.
09:07
Hab ich ein bisschen noch nicht gesagt. Ich sag's hier kurz. Doch, hier käme es. Jetzt ärgert er mich gerade.
09:25
Ja. JavaScript selber ist so der Name der Sprache, den man immer benutzt. Letztlich ist es aber ECMAScript. ECMA ist ein Standardisierungsgremium, so wie die Sprache C zum Beispiel von ANSI kommt. Es kommen also verschiedene Parteien zusammen,
09:42
Privatpersonen, Firmen, wie auch immer, so wie das Geld halt da ist. Und entwickeln zusammen die Sprache. Und letztlich ist die Basis für JavaScript ECMAScript. In Flash gibt es zum
10:04
Beispiel die Dom API, die sich mit dem Browser interagieren kann. Von der Syntax her ist es aber das Gleiche. Und es gibt immer zwei Schreibweisen. ES, also ECMAScript. Fünf ist das gleiche wie ECMAScript 2016. Also die Jahreszahl ist quasi eine Zahl höher,
10:23
wenn man so möchte. Aber es gibt auch zwei Schreibweisen. Und was TypeScript macht ist, es unterstützt auch zukünftige ECMAScript Features, also die wir noch nicht in unseren Browsern haben. Und ist in der Lage, die zurückzuportieren auf eine aktuelle ECMAScript Implementierung. Beispiel,
10:40
nehmen wir an, Firefox implementiert ECMAScript Version 5. TypeScript bietet aber Features aus ECMAScript 6, die schon standardisiert sind, abgenommen, aber noch nicht im Browser vorhanden. Dann kann ich die trotzdem jetzt schon benutzen mit TypeScript und der Compiler übersetzt das für mich zurück. Wir haben natürlich die Fragen auf, wieso geht das immer? Und es geht halt auch nicht immer.
11:01
Es hängt von den Sprachfeatures ab, die ich nutze. Es gibt ein, zwei, die setzen Unterstützung in der Laufzeitumgebung voraus, also in der virtuellen Maschine. Da kann logischerweise ein Transpiler, der nur Syntax transformiert, das nicht für mich automatisch machen. Wenn ich dann aber diese Features nutze und ich sage, mein Tage ist ECMAScript 5, dann würde der Compiler sagen,
11:23
du nutzt gerade dieses Feature. Ich kann dir das nicht zurückkompilieren auf dieses Sprachniveau. Aber das kommt so gut wie nicht vor. Das letzte Mal so Async Functions zeige ich nachher mal. Und das haben wir bald auch hinbekommen. Also das zurückzuportieren. Und eigene Features, und die zeige ich jetzt natürlich.
11:42
Das ist das einfachste Beispiel für TypeScript Code. Und zumindest dürften alle dann gleich denken, das sieht aus wie JavaScript Code. Ist es auch. Das ist auch eine Definition von TypeScript, dass syntaktisch gültiger JavaScript Code ist auch immer syntaktisch gültiger TypeScript Code.
12:00
Das heißt nicht, dass der Compiler nicht schon was zu meckern hätte. Also in dem Fall jetzt nicht. Das ist alles gut. Also der Compiler würde schon seine Logik los schießen. Aber syntaktisch ist das korrekt. Hier mal so das naheliegendste Feature von TypeScript. Das ist im Grunde wie das davor. Mit dem einzigen
12:20
Unterschied, dass hier der Parameternahme, ich lasse das mal so markiert, Doppelpunkt und dann eine Typannotation. Jeder kennt Java, nehme ich an, dann würde ich das mal zum Vergleich ziehen. Wenn nicht, einmal kurz die Hand hoch. Wunderbar. Das ist das Gleiche, als würde ich wie ein Java den Typen davor
12:41
schreiben, natürlich mit dem Leerzeichen getrennt, schreibe ich das hier mit einem Doppelpunkt getrennt dahinter. Das hat gute Gründe, sehen wir gleich. Und das ist auch nicht TypeScript, die das erfunden hätten, das so zu machen. Scala macht das so und ich glaube ML-Dialekte letztlich. Aber letztlich ist TypeScript nicht die erste Sprache, die das so nutzt und es gibt wie gesagt
13:01
einen guten Grund. Wenn ich nichts schreibe, dann wird auch nichts bemeckern.
13:25
Das ist auch mit Absicht, man hätte ja auch den anderen Weg wählen können, dass ich ihm alles sagen muss, was geht, aber ich kann den anderen Weg ebenfalls gehen und sagen, ich sage dir nichts darüber, was geht, und dann kann ich auch alles damit machen. Man kann ja auch alles damit machen. Das macht auch Sinn, weil zur Laufzeit ist
13:41
es alles JavaScript-Code und man kann sich nur bedingt komplett von dieser Semantik entfernen. Realistisches Beispiel wäre der untere Codeblock, dass ich nicht sage any, sondern ich sage, das ist ein String, also logischerweise ein String, kleingeschrieben in dem Fall. Und jetzt wird der Compiler überprüfen, dass wenn ich diese Funktion aufrufe, ich
14:08
kann die Funktion aufrufen. Das sieht man nachher immer mehr. Das Ausschnitt von den typischen Typen, Boolean, Number, String, Arrays, und so ein Inam einfach mal als ein
14:21
Beispiel, es gibt mehrere solcher Sachen, nur dass man mal sieht, da ist mehr als nur die JavaScript-Typen. Solche Sachen, da tobe ich mich aber nicht drüber aus, jeder von euch kann sich die Anleitung durchlesen, ich will ja nur ein bisschen neugierig machen und dann schaut ihr euch eh noch zu Hause immer an, was es da alles gibt. Der Grund, warum man sich
14:40
eben für diese Syntax entschieden hat, also doppelpunktgetrennt dann hinten der Typ, ist, ich kann das auch weglassen, das habe ich ein bisschen gelogen, bei der Funktion, wenn ich es nicht angebe, ist das wie ein Any. Das liegt daran, dass TypeScript schaut sich diese Funktion an, sieht den Parameter und kann nichts darüber
15:02
aussagen. In diesem Fall ist die zweite Zeile, wenn ich das weglasse, kann der Compiler aber was erkennen, denn ich weise ja ein Boolean zu. Und das ist das, wenn ich das weglasse. weise ja ein Boolean zu. Dann gehe ich hin und markiere diese Variable als
15:21
Boolean. Type-Inferencing, die das Uni-Zeiten durch Haskell kennen, das wird da ins Extrems getrieben, da würde das mit der Funktion auch
15:47
ein Boolean geben und das setzt erst mal voraus, dass ich den ganzen Code-Basis kenne und auch für Performance ist es logischerweise nicht gut. Deswegen hier wird der Compiler nicht sagen, B2 ist ein Any, sondern es ist ein Boolean, sodass ich das
16:00
hier auch machen kann, also B1 kann ich B2 zuweisen. Typischer JavaScript-Code, ich lege eine Variable an, Person mit dieser Struktur, FirstName, LastName. Das davor, also ich hatte bisher nur Strings und Numbers so was gezeigt,
16:21
so könnte ich eine Struktur beschreiben, Interface kennt man denke ich auch aus Java, genau die gleiche Syntax drum herum zumindest, also Interface, Person und das sind dann die Member, die Properties in meiner Struktur, die ich beschreibe und auch hier das gleiche Prinzip, erst der Name der Variable und dann der Typ. Und so könnte ich das verwenden,
16:42
das ist das Beispiel von hier oben mit dem Typen hinten angegeben, also Doppelpunkt Person und damit markiere ich diese Variable vom Typ Person und der Compiler überprüft jetzt, dass diese Struktur, die ich hier übergebe oder zuweise, dass diese Struktur kompatibel ist zu der Struktur, die hier
17:01
im Interface definiert ist. Das ist auch eine ganz wichtige Eigenschaft von, das zeige ich noch kurz, das ist jetzt das letzte Beispiel von der Folge davor, also ich habe eine Struktur vom Typ Person, habe eine Funktion, wo ich sage, ich akzeptiere Parameter von diesem Typen, entsprechend überprüft der Compiler,
17:21
dass ich es auch nur damit aufrufe und hier innen drin habe ich eben meinen korrekten Zugriff, der von dem Compiler wieder sichergestellt wird. Das gebe ich mal kurz. Ich habe hier kurz gesagt, dass es überprüft, ob das, was ich zuweise, strukturell
17:40
kompatibel ist zu dieser Struktur. Wenn man mit der Java-Brille ein bisschen drauf guckt, dann ist das komisch. Man würde erwarten, dass ich hier eine Klasse mache, die dieses Interface implementiert und dann kann ich das zuweisen. Das geht natürlich auch, aber selbst wenn, es wäre nicht das gleiche Verhalten. Java ist ein sogenanntes nominales
18:02
Typensystem. Das heißt, der Name entscheidet, der Name Person, der Name Person Klasse, wie auch immer. Und wenn die die gleichen Namen haben, dann sind die kompatibel. Das macht TypeScript nicht. TypeScript vergleicht immer die Struktur. Wenn ich zwei Sachen einander zuweise, schaut er nur, was ist in der Inhalt, was sind die Parameter,
18:21
also die die Member, die Properties, was sind deren Typen und was weißt du zu. Und wenn das Compatibel ist, dann ist der Ausdruck kompatibel. Ich tippe mal kurz hier ein Beispiel, mache ein Interface, so der Klassiker, HasLength und sage, das Ding hat eine LengthProperty vom Typ
18:42
Number und ich schreibe eine Funktion, die erwartet etwas von diesem Typen. Und dann, also man sieht, wenn ich jetzt hier tippe, krieg ich mein CodeCompletion, Length möchte ich davon ausgeben.
19:01
Und jetzt lege ich mal zwei Variablen an. Das eine ist ein String, das andere ist ein Array. Und beides hat eine LengthProperty. Der String hat eine LengthProperty, das ist logisch, Anzahlzeichen. Und das Array hat auch eine
19:22
LengthProperty. Und deswegen kann ich beides der Funktion übergeben. Der Compiler ist damit einfach schon, als würde es rot werden, wenn ich das missmachen würde. Weil eben A und B sind strukturell kompatibel zu dem,
19:41
was ich hier oben angebe. Wenn ich jetzt hier was Neues mache, dann meckert er jetzt hier unten. Ich hoffe, man kann das noch lesen. Er sagt, das Argument vom Typ String, das A, ist nicht zuweisbar zum Parameter auf Typen HasLength.
20:01
Dann mache ich das wieder weg. Geht's. Anfangsungewohn ist aber eigentlich ganz schön, weil es hilft, die Typen-Hierarchie, die man so in seinem System hat, ein bisschen flach zu halten. Ich brauche nicht für alles explizit wie ein Interface. Ich muss nicht alles im Namen geben. Ich kann einfach die Struktur beschreiben. Ich hätte das auch gar nicht hier so
20:22
machen müssen. Ich kann auch den Typen quasi hier, inline definieren. Ich kann sagen, das Gleiche von oben. Jetzt mache ich das hier weg. Das wäre gültig. In Java müsste ich für alle Objekte,
20:40
die ich so behandeln will, müsste ich sicher gehen, dass sie das gleiche Interface implementieren. Ein Beispiel von String und Limitlisten wird da schon nicht gehen. Die haben zwar beide Length, aber die implementieren kein Interface dafür. Da habe ich schon das Problem. Interfaces,
21:00
so wie ich das jetzt getippt habe, tippt man es natürlich selber selten, die nur das Ganze mal ein bisschen zu zeigen mit dem strukturellen Typisierung. Selbst schreibt man Klassen. Einfaches Beispiel, statt Interface schreibe ich Class, hier meine Properties, instanziere das mit der gleichen Sintakt, wie ich das in Java kenne, und kann
21:22
dann hier unten direkt die Werte zuweisen, wie hier. Was ich jetzt nicht zeige, ich sage es kurz, in Java würde man ja mit Get Assetten bei sowas arbeiten. Kann man hier natürlich machen. Man könnte aber auch, wie das C Sharp zum Beispiel macht, dass ich ein Property,
21:41
also explizit kann ich sagen, das ist ein Property mit diesem Getter, mit diesem Setter. Dann hätte ich immer noch diese Sintaks, aber beim Aufruf wird das über einen Setter gehen, wo ich was damit machen kann. Also für die, die das C Sharp kennen, die wissen, was ich meine, ansonsten sprengst du den Rahmen. Auch hier wieder strukturelle Typisierung.
22:01
Person ist jetzt eine Klasse. Ich sage hier eine Variable von diesem Typen. Und ich weise einfach ein Objekt literal zu. Ich instanziere da gar nicht die Klasse, wie ich das auf der Folie davor gemacht habe, wie hier. Ich weise einfach direkt was zu. Das geht, weil diese Struktur kompatibel ist
22:21
zu dieser Struktur. In der Praxis macht das natürlich keinen Sinn, weil man hätte in einer Klasse üblicherweise auch wie hier Funktionen. Und wenn ich das jetzt hier unten so mache, dann meckert der Compiler. Denn in dem Fall wird er sagen, die Struktur hier unten, die hat keine Say Hello Methode. Also man kann damit jetzt keinen Mist bauen.
22:41
Das ist nur wieder um zu zeigen, dass es tatsächlich strukturell typisiert ist. Konstruktor, logischerweise. Minimal anders als in Java. Ich schreibe Konstruktor und nicht den Namen der Klasse. Dann hier die Parameter, wie gehabt. Name, Doppelpunkt, der Typ, mit Komma getrennt.
23:00
Das ist so ein Klassiker, den man als Java-Programmierer immer macht. So die POJOs. Ich habe hier meine Instanzvariabeln. Die akzeptiere ich, oder einen Teil davon akzeptiere ich als Konstruktorparameter. Und in meinen Konstruktor weise ich die zu. Ein gängiges Muster, denke ich, kennt jeder. Das ist immer nervig zu tippen.
23:20
Hier über This greife ich dann auf meine Membervariabeln zu. Anders als in Java ist das This auch Pflicht. Also ich kann es nicht weglassen. Ich muss This tippen. Also hier instanziere ich die Person und rufe die Methode auf. Weil das so ein gängiges Muster ist und das ziemlich nervig ist, wir haben ja Firstname hier eins,
23:41
zwei, drei, viermal stehen. Für letztlich total stupiden Mist. Kann ich in dem Konstruktor, bei der Parameterliste, kann ich vor den Parameter einen Modifier schreiben. In dem Fall Public. Ich hätte auch Private schreiben können.
24:02
Modifier gibt es so, wie man sie kennt. Zeige ich nicht extra. Und jetzt wird daraus automatisch eine Instanzvariable, ein Property. Das wird automatisch zugewiesen. Also ich kann wie gehabt hier unten darauf zugreifen über This. Und für den Aufrufer ist es erstmal nur ein Parameter.
24:29
Die Frage war, ob es ein Fehler wäre, wenn ich in der Klasse Person noch eine Methode Person hätte.
24:40
Nö, das ist ja ein anderer Namensraum. Also Methoden, also der Inhalt einer Klasse, da ist ja kein Konflikt von der Benamung her mit der Klasse selber.
25:01
Ja, das stimmt. Deswegen ist es ein Problem, über This zuzugreifen. Und dann ist klar, was gemeint wird. Die Klasse wäre ja wie global, zumindest in dem Scope vorhanden. Aber wenn ich jetzt hier einen Member hätte,
25:20
dann ist es ja gültiger Code, im Grunde so was zu haben. Person wäre die Klasse, also das erste. Und das wäre jetzt die Funktion, um die es gerade geht. Und dadurch, dass ich ja in dem Person über This Punkt darauf zugreifen muss, ist klar, wohin ich hin will. Wenn ich das This nicht schreibe, würde ich die globale Klasse meinen.
25:41
Schreibe ich This, meine ich den Member. Aber ich kann es gerne einmal tippen. Ich mache das hier alles weg, das brauchen wir ja nicht. Also es gäbe dann hier den Member Person.
26:00
Ja. Ach so, ja. Kann ich auch machen. Ja. Ja, aber ob es eine Funktion ist, das spielt keine Rolle. Ich mache mal noch ein A, damit es ein bisschen klarer ist, vielleicht fürs Auge. Also ich habe jetzt hier einfach
26:20
zwei Member. Und in meinem Konstruktor könnte ich jetzt sagen, also ich kann die äußere instanzieren. Und der Konflikt mit der Funktion besteht nicht, weil ich greife entweder so darauf zu oder eben so. Also es ist immer klar,
26:42
wo ich hin will. Es gibt kein Overloading, weil das müsste die Runtime unterstützen.
27:02
Und ein Overloading geschieht immer anhand von welchen Typen wurden wir übergeben. Da aber die JavaScript-WM keinen Dispatching basierend auf dem Typen hat, würde das nicht gehen. Man kann aber mehrere Signaturen deklarieren. Und da muss man einen Konstrukt implementieren, der kompatibel dazu ist.
27:21
Das macht man indem man z.B. Parameter als Any markiert oder Union Types, Optional Types. Und dann da drin guckt, welchen zu welcher Deklaration passend hast du mich jetzt aufgerufen. Also für den Aufrufer wird es gehen. In Bezug auf Typen. Typensysteme, kurz ein bisschen
27:40
Theorie, wird ja immer verglichen, statisch versus dynamisch, Java versus Python, wie auch immer. Da werden aber in der Regel zwei Attribute vermischt, die man eigentlich getrennt betrachten muss. Das erste Attribut ist, wann der Typ geprüft wird. Und die Antwort darauf lautet, immer statisch oder dynamisch.
28:00
Das erkenne ich in der Regel daran, dass eine Sprache irgendwo so ein Konstrukt hat. Das ist dieser Typ. Das war jetzt bei uns hinten mit dem Doppelpunkt. Dass ich den weglassen kann, okay, aber es ist per Inferencing quasi immer noch da. In einer dynamischen Sprache sind es einfach wie Symbole. Und ich weiß denen Werte zu. Und ist es hier ein String
28:22
und ein Statement weiter, ist es ein Number. Daran würde ich das in der Regel erkennen. Die andere Frage ist, wie streng der Typ geprüft wird. Bei einer schwachen Typisierung hier ein Beispiel, ich addiere einen String und einen Number. Das würde in Java ja zum Beispiel gehen. Die Regel ist einfach, wenn ich mit einem String
28:40
etwas konkatiniere, wird auf alle anderen Operanten Two String aufgerufen. Ist sicherlich nicht das schlimmste Beispiel für schwache Typisierung. Schlimmer ist, wie ich das vorhin mit Not a Number gezeigt habe. Zeigt aber, dass es diese Achse gibt. Anderes Beispiel, wie hier, ich habe einen String Zahl und addiere die 5 und ich muss explizit
29:01
per str, also der String Funktion das konvertieren. Das obere, das was noch markiert ist, ist ein Beispiel aus Java. Das untere ist ein Beispiel aus Python. Also eine Sprache, die dynamisch typisiert ist, ist in dem Fall strenger typisiert als Java. Und das zeigt, dass es wirklich zwei verschiedene Achsen sind, die man betrachtet.
29:20
Und das hier gleich deswegen, weil TypeScript in dieser Klassifizierung wirklich ein Exot ist, denn es ist statisch typisiert. Ich habe einen strengen Compiler, der ist sogar sehr streng, wenn ich nicht gerade any hinschreibe. Es ist aber, oder es bleibt weiterhin schwach typisiert. Das liegt daran, weil die virtuelle Maschine immer noch JavaScript ist. Der Compiler
29:40
macht aber immer mehr, von Version zu Version, kamen immer mehr Prüfungen rein, dass ich es eigentlich nicht mehr schaffe, Miss zu programmieren. Also diese Not a Number Fehler, die fängt eigentlich der Compiler schon. Das kriege ich nur dann hin, wenn ich über any Werte ihm quasi die Prüfung ausschalte, ihm dann Mist gebe, dann habe ich wieder
30:00
not a Number. Wenn ich aber meine Typen mit Strings, mit Number etc. annotiere oder das entfernen lasse, dann fängt der Compiler mittlerweile all diesen Mist. Das haben wir vorhin gesehen, als ich hier versucht hatte, diesen JavaScript-Batman zu machen. Da wurde ja alles rot und er hat gesagt, das und das geht nicht.
30:22
Ich husche jetzt weiter durch die Features. Var ist der übliche Weg in JavaScript Variablen anzulegen. Hier mal so eine Frage in die Runde. Ich lege zwei Variablen an a und b, mache dann hier einen Block auf, if true, einfach nur, wenn ich einen Block habe, schreibe da drin wieder a, wie hier oben das a war, a gleich 10 und b gleich 20 und gebe dann a und b
30:42
aus. Also ich fange an mit 1 und 2 und 10 und 20 hier drin. Wer glaubt, dass das Ergebnis hier unten 1 und 20 ist? Ein Drittel, würde ich mal sagen.
31:00
Also es ist interessant, weil es immerhin heißt, dass ein Drittel des Raums falsch liegt bei so einer Sprache wie JavaScript, die irgendwo banal ist. Das Problem ist, dieser Drittel hat jetzt gedacht, das wäre ein Block und das JavaScript lexikalisches Scoping hätte. Also dass ein Block ein neuer Scope ist, ist aber nicht der Fall. JavaScript kennt genau nur ein Scope
31:21
und das ist Function Scope. Das heißt, alle Variablen, die ich deklariere, die rutschen nach oben, die babbeln nach oben bis da, wo die nächstumschließende Funktion ist. Das heißt, dieses war a ist redundant zu dem hier. Das ist aber die gleiche Variable. Deswegen gibt es,
31:40
das hatte ich vergessen zu sagen, ein paar Features, die ich zeige, sind nicht nur TypeScript, sondern auch durchaus in der neuen ECMAScript-Version. Ich habe mir jetzt aber mal gespart, immerhin zu schreiben, ob das auch in ECMAScript ist. Statt war schreibe ich let und let ist dann tatsächlich lexikalisches Scoping. Also dann hätte auch dieser Drittelrecht dann wäre dieses a wirklich ein anderes a als das hier
32:02
oben und dann wäre die Ausgabe 1 und 20, genau wie gehabt. Hier wäre sie gewesen 10 und 20. Also dieses a ist letztlich dieses a.
32:22
Die Deklaration der Variable rutscht nach oben, nicht die Zuweisung. Genau, also ein vernünftiger Editor
32:40
Frage wiederholen. Frage, ob ich wirklich zweimal wahr schreiben kann. Es ist kein Fehler. Also jeder Editor würde das bemängeln. Also man hat ja mittlerweile in den Editoren so ein Linting auch mit drin. Aber es ist aus Sprache der JVM, der Virtual-Maschine, aus Sicht der Virtual-Maschine kein Fehler. Deswegen immer let und ich sage mal,
33:01
das ist das Post-it am Monitor, immer let schreiben und das aber auch wieder weg, sondern Post-it und const hinmachen. Das ist genau wie let, hat also auch lexikalisches Scoping, ist aber quasi wie ein Final. Also ich kann den Wert nicht neu zuweisen. Und das einfach angewöhnen, räumt den Code auf. Ich sage mal 9 von 10 Variablen verändere ich eigentlich nicht mehr, nachdem ich sie
33:21
deklariert habe. Die bekommenden Wert sind letztlich ein Shortcut vielleicht von der Berechnung, von dem Rückgabewert. Und ab dann mache ich mit dem Wert weiter. Und dass ich immer neu zuweise passiert, sehr selten, 10% vielleicht. Deswegen immer const ist das schönere Schlüsselwort in dem Fall dafür. Wie ein Final in Java.
33:40
Auch ein wunderschöner Bug in JavaScript. Das, ich nenne es mal this bug, aber es ist kein Bug, ist tatsächlich ja so gewünscht. Wir fangen mal hier oben mit einem Array an, 123. Dann eine Klasse, hier mal als Beispiel so ein Modifier, spielt aber keine Rolle, entscheidet sich, ich habe hier so eine Instanz Variable n mit dem Wert 1.
34:01
Dann habe ich eine Funktion iterieren. Und dann sage ich, okay, iteriere über alle Zahlen. Hier oben. Und dann übergebe ich ihm für jeden Durchlauf ein Callback, also diese Funktion. Die wird also für jeden Eintrag hier oben aufgerufen. Und dann gebe ich aus, die Zahl, das ist dann der jeweilige Eintrag,
34:21
plus this Punkt n. Ich habe es natürlich schon gespoilt. Steht ja auch hier ein Fehler. Weiß jemand warum? Oder wer hätte gewusst, dass es ein Fehler ist? Das ist eigentlich viel schöner. Okay, also dann sage ich mal zweieinhalb. Das Problem ist, dass dieses this erst recht für Java-Programmierer
34:41
total irreführend ist. Man könnte das besser nennen invoker. Denn der, der die Funktion aufruft, der bestimmt, was da drin das this ist. Punkt. Das ist ein this. Wenn ich jetzt, wie hier, so was mache, jetzt ist natürlich das hier ein ganz kleines Beispiel.
35:02
Wenn ich jetzt so diese Funktion aufrufe, dann ist das syntax. Das bedeutet, dass das, was vor dem Punkt steht, reiche das in die Funktion als this rein. Deswegen invoker. Das ist die einzige Stelle, wo JavaScript mir hilft. Syntaktisch ist es das gleiche, als würde ich hier ein apply aufrufen.
35:22
Ihm dann sagen, das ist ein this-Argument und du bekommst keine Parameter. Also ziemlich gaga das Ding, das this zu nennen und sich darauf zu verlassen. Deswegen ist dieses this, würde ich das so testen, wäre das globale Objekt. Quasi im Browser wäre das Window.
35:42
Hängt ein bisschen davon ab, ob ich diesen use strict Flag einschalte. Wenn ich use strict einschalte, was man immer machen sollte, ist this in dem Fall zumindest undefined. Dann kriege ich eine Fehlermeldung, dass ich auf undefined das end nachschlage. Wenn ich das aber nicht einschalte, wäre das das globale Window-Objekt.
36:01
Also der Fehler ist, diese Funktion, da drin verliere ich das this, das äußere is, weil der, der das aufruft, nicht mir wieder neu reinreicht. Dafür gibt es dann die arrow-functions, einfach eine andere syntax. Ansonsten ist der Code der gleiche. Statt function und jetzt kennt man, habe ich hier meine Parameterliste. Wenn ich nur ein Parameter habe,
36:22
kann ich die Klammern weglassen. Dann mache ich einen Fett-Error. Nimmt man Fett, weil zwei Gleicherzeichen sind. Andere Sprachen wie Java 8 macht thin arrows, das ist mit so einem Minosymbol. Also dann diesen Fett-Error und dann den Block. Wenn ich jetzt mehrere Zeilen habe, mache ich das mit geschweiften Klammern. Brauche ich hier
36:41
gar nicht, wenn das nur ein Statement ist, kann ich die geschweiften Klammern auch weglassen. Und diese arrow- Funktion ist die Capturing. Das heißt, die schaut, was ist um mich herum? Der this-Scope macht ein Capturing. Das sieht man, würde man den Code finden unter wird eine Variable angelegt, this-unterstrich gleich this.
37:01
Und dann ist die gecaptured. Und hier drin wird jeder Zugriff auf this umbenannt in this-unterstrich. Dann wird diese gefangene Variable quasi referenziert. Frage war, ob das jetzt TypeScript Features oder ECMAScript. Das ist in dem Fall auch ein ECMAScript Feature.
37:21
Das optional skippe ich auch. Das und das skippe ich. Ich würde lieber noch zurückgehen, aber ich möchte lieber noch ein bisschen tippen. Hatte mir noch ein paar schöne Beispiele für Livecoding aufgehoben. Das ist IntelliJ. Ich gleich mache eine Folie über Tools.
37:42
Ich muss leider so ein bisschen gebückt stehen. Ich hoffe, kann man das so mit dem Mikrofon gut hören? Ich zeige jetzt einen Feature. Das sind sogenannte Strict Nullchecks. Die muss ich im Compiler einschalten. Es gibt eine Datei, die ich in meinem Projekt immer habe, die ts-config. Ich zeige jetzt nicht alles, in dem Fall nur diesen Eintrag.
38:01
Standardmäßig ist das false. Und damit schalte ich eine strengere Nullprüfung ein. Was heißt das? Ich sage, ich lege hier eine Variable an und weise eine 1 zu. Jetzt Inferter Compiler. Ich müsste es jetzt nicht hin tippen. Ich mach's mal. Das ist vom Typ Number. Das ist das Gleiche.
38:20
Wenn ich jetzt eine Zeile drunter das hier schreiben möchte, in Java wird das gehen. In TypeScript nicht. Er würde sagen, Null kann ich nicht zuweisen. Das ist dieses Verhalten, das ich einschalte mit dem Strict Nullcheck. Kurz ein bisschen Theorie. In Sprachen, die Klassen, die bilden ja eine Hierarchie.
38:42
Und ich habe zwei Spezialfälle in dem Ganzen. Ich habe einen TopType. Das ist in Java ein Object. Und ich habe Bottom Types. Das ist zum Beispiel ein Null. Klingt ein bisschen komisch. Aber zu dem Wert Null muss so ein Mathematiker, Typentheoretiker sich ja auch irgendwie den Typen Null überlegen.
39:00
Und wenn ich ja den Wert Null überall einsetzen kann, dann muss das ja ein Typ sein, der implizit von allen vererbt, den ich überall einsetzen kann. Das ist mit Bottom Type gemeint. Und mit diesem Strict Nullcheck deaktiviere ich dieses Verhalten. Da ist Null komplett disjunkt und kein Bottom Type mehr. Andere Sprachen überlegen sich da speziell Konstrukte.
39:23
Optional in den Java 7 kamen das. Ich glaube 8. Ich weiß gar nicht genau. Davor in Java hat man eigentlich immer länger benutzt. Weil dieser Null Pointer-Bug letztlich nervt. Ich glaube auch der Finder von, da war das Scheme, ich weiß es nicht, der Null erfunden hat, hat auch gesagt, das war der
39:41
One Billion Dollar Mistake. Das Konzept von Null ist, dass jeder hier, der auch eine halbe Was mit Produktivsystem zu tun hat, kennt Null Pointer Exception im Log. Das wird jeder haben, bin ich mir 100% sicher. Und es ist einfach ein Loch im Typensystem, mit dem ich nur Mist bauen kann. Kann ich hier ausschalten? Natürlich ist dann die Frage,
40:02
aber Null ist auch so wie optional. Das ist das nächste Feature, denn ich kann in TypeScript gibt es sogenannte Union Types mit dem, mach ich so ein Oder-Symbol. Und dann kann ich sagen, diese Variable ist Null, Number oder Null. Ich kann es auch
40:20
beliebig viele machen, ich kann es sagen, oder ein String. Jetzt kann ich das hier machen. Ich muss hier mal eben Mist tippen. Ich lasse es kurz so, dass ihr noch mal seht, was der compiler alles macht. Und wenn ich jetzt auf Blat zugreifen will, das ist es, er bietet mir jetzt hier gerade das Code Completion für die Number an.
40:42
Das ist, weil der Compiler weiß, dass nichtsdestotrotz das Ding eine Number sein wird. Der erkennt den Kontrollfluss in dem Code. Deswegen muss ich ihn mal kurz hier ärgern, mit diesem S-Any das ausschalten. Und jetzt habe ich hier eigentlich nur noch Mist. Das ist jetzt mehr so IntelliJ, der hier meint, mir alles mögliche anzubieten.
41:00
Ich kann jetzt hier nicht sagen Blah, Sub-String, 2, das wäre so ein Wert für String. Dann sagt er zu Recht. Property Sub-String does not exist on Type String oder Number. Deswegen kann ich einfach sagen If Blah, Instance of
41:21
String. So würde ich das machen als JavaScript Programmierer. Und das schöne TypeScript hat sich da gar nicht ein neues Konzept überlegt, sondern die sagen einfach
41:41
wir verstehen ab sofort, was ein Type of an Instance of ist. Und jetzt weiß der Compiler, dass da drin muss Blah ein String sein. Ich muss auch gar nicht casten jetzt. Also der Compiler weiß in dem If ist es ein String. Entsprechend kann ich jetzt hier drin auf alle Stringwerte zugreifen. Ich mache nochmal ein anderes Beispiel. Ich mache mal
42:01
ein String Array. Weil String Array und String haben ja beide die Length Methode. Deswegen mache ich jetzt mal was anderes. Und zwar sage ich, wenn Blah ungleich Null, dann muss es jetzt ja ein String Array oder ein String sein. Entsprechend kann ich darauf Length zugreifen, weil das beide haben.
42:20
Sowohl String Array als auch String. Ich könnte auch weitermachen. else if, was hatte ich? Type of Blah gleich gleich String. Jetzt weiß er, dass es ein String ist.
42:42
Der ist ja gerade zu schlau wieder, weil ich das hier oben so mache. Das einfach kurz ignorieren. Und im else Branch weiß er, dass das ein Array ist. Also die Meldung, die er jetzt hat, ignorieren. Das ist weil er immer noch zu schlau ist. Ich müsste das jetzt hier wegmachen. Wenn ich das aber so mache, dann weiß er immer noch,
43:00
ich weiß das nie zu. Das wird never sein. Grundsätzlich ist es aber korrekt, was ich hier zeige. Ich müsste es ja auch da rein machen.
43:29
Vielleicht reicht es doch. Ja, super, danke. Also ich hätte dich auch als verketten müssen, aber so hatte ich jetzt das falsch verschachtelt. Hier drin weiß ich das Kanal. Da muss es das oder das sein. Und man sieht, er erkennt,
43:41
dass dieser else, es muss jetzt ein Array sein. Sonst könnte ich hier ja nicht push aufrufen, die Array Methode. Das Schöne ist, wie gesagt, keine neue Syntag, sondern das ist genau der Code, den man in JavaScript für so was machen würde. So, ich würde es wegmachen, wenn es keine Fragen dazu gäbe.
44:11
Ich habe die Frage leider akustisch nur halb verstanden.
44:25
Also die Frage war ob String vom Array oder Number. Ich hätte jetzt hier noch String. Vielleicht machen wir es nachher gleich am Ende nochmal kurz, weil ich verstehe die Frage auch akustisch leider nur so halb.
44:42
Ja, das würde gehen, weil das ist immer noch valide. Ich könnte jetzt hier drin, ich hoffe, das ist die Frage, ob ich jetzt hier noch Strings addieren kann. So was. Ja,
45:01
da müsste ich ja hier oben den Number haben. Und dann muss ich hier, ist diese Prüfung jetzt natürlich falsch, deswegen ich hatte jetzt ja mit String und String Array. Würde ich, machen wir mal so, wenn es Number ist, dann kann
45:23
ich damit ganz normal die Number Operation machen.
45:42
String oder Number? Ja, genau, also ich wiederhole die Frage nicht, weil im Grunde ist die Frage, ob das geht.
46:01
Da sagt da dieser Operant plus gleich, also Addition geht nicht auf String oder Number. Und wenn ich das mit dem String mache, geht es und ab dann ist Plan String.
46:25
Genau, das ist einfach nur, die Frage war, warum ich hier dieses Konstrukt stehen habe. Das ist nur, damit ich es demonstrieren kann. Der Compiler analysiert relativ clever den Codefluss. Und wenn ich nur schreibe gleich eins, dann weiß er in Zeile vier,
46:40
ist es eine eins. Und dann ist so eine Prüfung, das muss ein Laufzeitfehler sein. Wenn ich jetzt hier das als String behandle, das wird ein Fehler sein. Und damit ich diese Prüfung ausschalte, ärgere ich ihn einfach nur und zwinge es als Any zu betrachten. Und damit markiere ich diesen Wert eins als, ignoriere, dass es eine eins ist, tue so, als wäre alles mögliche.
47:12
Richtig, weil mir die Frage war, ich hatte vorhin String oder Null oder String Array.
47:20
Und das, was ich hier angebe, passt in keinster Weise zu dem hier. Völlig korrekt, ist auch ein blödes Beispiel von mir dann in dem Fall gewählt. Es hat funktioniert, weil ich mit dem Any ist wie ein Cast. Ich caste diesen Wert, den Value eins auf ein Any und Any schaltet die Tütenprüfung aus. Und ab dann kann ich Mist bauen. Deswegen das nie machen. Nur ich brauche das in dem Fall, um einfach tippen zu können.
47:49
Map Types. Dafür kopiere ich mir ganz kurz Code. Das ist so ein gängiger Use Case, den man eigentlich in der Frontend Programmierung hat. Z.B. ein Kollege von uns hat ein Tool geschrieben,
48:02
um aus unseren Java Klassen, die wir am Server haben, automatisch TypeScript Interfaces zu generieren. Macht Sinn, weil über Rest Interfaces kommen diese Typen ja zum Kleinen und wieder zurück. Und damit wir was nicht doppelt tippen müssen, haben wir so einen Compiler Plugin geschrieben. Das heißt, wir haben im Frontend solche Interfaces, wie in Zeile eins bis fünf.
48:22
Wenn wir aber damit arbeiten wollen, oft sagen wir, wir legen jetzt ein leeres Objekt davon an, das rutscht erstmal durch Formulare und ganz am Ende schicken wir das zum Server. Das sähe dann irgendwie so aus, dass ich sage, okay, Person ist, puh, ja, Person ist ein leeres Objekt.
48:40
Und dann will ich eigentlich danach, nach und nach darauf zugreifen. Das Problem ist, dass er mir an dieser Stelle schon meckert. Weil das, was ich rechts ihm zuweise, dieses Objekt total, passt nicht strukturell zu dem hier. Bei drei Werten wäre das nicht so schlimm, aber wenn da 20 Werte drinstehen, ist das
49:01
nervig, wenn ich alle wiederholen müsste. Was ich dann mache, machen könnte, bitte nicht machen, ist, das hätte der Kollege so machen können, dass das Interfacewasser generiert wird. Mit dieser Syntax werden alle Member als optional markiert.
49:20
Das ist dasselbe, als würde ich schreiben, String oder undefined. Hat aber eben auch zur Folge, dass jetzt alle Werte optional sind. Entsprechend muss ich auch prüfen, wenn ich jetzt darauf zugreifen möchte.
49:46
In dem Fall wird es gehen, undefined to String. Nur, ich will ja nicht, dass all meine Interfaces so aussehen, weil es fachlich wahrscheinlich immer noch falsch ist, dass es optional ist. Und dann gibt es in TypeScript die Möglichkeit, mit so einer generic Schreibweise, die
50:01
gehen, kann ich jetzt sagen, erzeugt einen neuen Typen, der übernimmt die Struktur von Personen, alle Werte da drin werden jetzt optional. Das heißt, es gibt keinen Grund, so was hier zu wiederholen, sondern ich kriege das so implizit. Und das Schöne daran ist,
50:21
dieses Feature geht nicht über Compiler-Magie, sondern das kann ich mir beliebig selber bauen. Es gibt noch ein Schlüsselwort Type, das ist im Grunde wie ein Alias, ein Shortcut für einen Typen. Ich könnte sagen, TypeX ist Number. Und ich kann nicht überall, wo ich sonst Number schreibe, könnte ich X schreiben.
50:42
Man sieht schon mal so was, dass ich sage, dann könnte ich hier sagen, TypStringArray. Also furchtbar, aber für komplexere Dinge vielleicht sinnvoll. Darum geht es aber nicht, sondern ich brauche diese Syntax, um diese Partials zu definieren.
51:03
Ich tippe erst mal kurz, dass ich jetzt sage, ich tippe es einmal kurz. Ach so, hier brauche ich natürlich Jane. Ich tippe es einmal hin, dann kann ich es danach erklären.
51:22
Und der kommt nach unten. Das ist genau das, was im Compiler nämlich steht.
51:43
Ach so, ja klar. Also ich erkläre sofort, worum es noch nicht geht. Aber was macht diese Syntax? Es ist wie so eine Interface-Definition, aber
52:00
ich habe hier eckige Klammern drum. Das kann man sich wie so einen Expand vorstellen. Und was ich hier sage ist, für jeden Key, für jedes Property in meinem Typen T, also generisch Typen T, für jeden da drin, den nehme ich jetzt unter P. Also für jedes P in T.
52:21
Das wäre dann Name, Age, Location. Wiederhole diese Zeile, das ist so mit den eckigen Klammern angedeutet. Und der Typ davon ist in meinem T das P wieder nachgeschlagen. Also ein bisschen Meter, das heißt ein bisschen, ziemlich Meter. Aber hier könnte ich jetzt sagen, deswegen merke
52:40
ich eben auch, jeden dieser Properties mache ich jetzt mit dem Fragezeichen hinten dran optional. Und schon habe ich eine generische Schreibweise, um für beliebige Typen in meinem System alle Members zu modifizieren. Ich könnte auch sagen, all meine Typen werden jetzt zum Beispiel Arrays mit ihren
53:00
gleichen Typen. Und was jetzt Person ist, ich mache hier wieder so kurz Ihnen ärgern, wenn ich jetzt Age nachschlage, dann ist es jetzt ein Array von Numbers. Also recht abgefahren. Das wird nicht nur genutzt für Partial, sondern auch
53:20
für Read-Only, dass man sagt, dieses Objekt darfst du nicht mehr modifizieren. Ich markiere alle Member als Read-Only. Das kann ich dann machen, indem ich hier vorschreibe Read-Only. Das ist natürlich Partial, ein blöder Name, also da mal drüber hinwegsehen. Und wenn ich jetzt versuche, was zuzuweisen, sagt er, ne geht nicht, can I assign to
53:40
because it's a constant or read-only property. Schon habe ich aus meinen generischen, also flexiblen Interfaces weiter Entwicklungen gemacht. Ja, bitte. Die Frage war,
54:16
wenn ich hier mit optional arbeite und ich eben alle Felder markiere
54:20
als optional, ob ich denn dann die Möglichkeit habe, zur Laufzeit zu fragen, hat Personen jetzt für alles ein Wert? Antwort nein. Weil, wenn ich hier es ist in dem Fall valide, keinen Wert zu haben. Deswegen gäbe es kein Konzept von hat alles einen Wert. Das müsste man quasi per Hand machen, dass ich über alle, ne doch schwierig. Ich wollte gerade sagen, man könnte
54:41
über das Objekt durch das iterieren und gucken, welche Werte da sind, aber ich weiß nicht, welche Werte da sein müssten. Deswegen besteht die Möglichkeit nicht zur Laufzeit.
55:03
Frage wiederhole ich nicht, ich beantworte sie, ich hoffe, es wird ein bisschen klar. Die strukturelle Prüfung findet zur Kompilzeit statt. Die Frage zielt darauf ab, kann ich zur Laufzeit da irgendwas prüfen? Ist das type of gleich oder instance of gleich?
55:20
Bezieht sich immer nur auf die Kompilzeit. Zur Laufzeit wird beim instance of nur geguckt, was wurde da mal instanziert? Und in dem Fall ist das hier keine Instanz von etwas, das ist ein plain object, das heißt, die Prüfung würde fehlschlagen. Das letzte Feature wäre
55:40
noch async-array, das gebe ich mir kurz wegen anderen Folien. Geht es um asynchrone Handlungen, kann ich nachher sonst machen und geht es sonst, wenn jetzt zum nächsten Termin ist. Module. Es gibt in JavaScript verschiedene Standards. Common.js ist das, was in Node verwendet wird. AMD ist eigentlich tot, kann ich mir merken.
56:01
Und in quasi jetzt der aktuellen JavaScript-Version gibt es auch native Module. Das Schöne ist, egal welche Typescripts unterstützt die alle, das ist ein reiner Compiler-Flag, zu welchem Modulsystem was den Code generieren soll. So sehen die Syntax aus, ich will auch nur antisen, dass es das gibt.
56:20
Entscheidend ist, eine Datei, in dem Moment, wo sie so einen Export stehen hat, oder ein Import hier unten, wird es automatisch zu einem Modul, dann ist es automatisch nicht mehr global, was hier steht. Das ist dann privat, quasi, die Klasse wird exportiert. Und dann kann ich mit dieser Schreibweise Utils aus der Datei mir die Sachen holen.
56:40
Will ich gar nicht mehr erklären, ich denke, jeder hat jetzt eine Idee, wie das aussieht und im Zweifel nochmal angucken. Das muss ich leider auch skippen. Bildsysteme, ich hatte mal eine Folie mit, es geht Grunt und Galp und das und dies, spart mir mittlerweile alles. Wenn ihr noch nichts habt, verwendet Webpack,
57:01
hier der Name. Das finde ich der sinnvollste und beste System. Wenn ihr ein anderes System verwendet, wie Galp, Grunt und Co, kann man das verwenden. Und dann würde ich jetzt eh nicht sagen können, verzichtet darauf und wechselt das. Also egal, was ihr einsetzt, man kann es einbinden, TypeScript, wenn ihr noch nichts verwendet, Webpack ist das schönste Tool.
57:21
Ich wollte unbedingt die Folie noch kurz zeigen, weil da die Frage schon war, welchen Editor ich benutze. An sich, alles opinionated, nur meine Meinung, jeder darf widersprechen. Die schönsten Tools aber für Entwicklung sind für mich derzeit die JetBrains Tools. Es reicht als Java-Programmierer, das IntelliJ ist super. Die Web-Tools, HTML,
57:41
SAS, CSS und Co und eben auch TypeScript ist auch exzellent und das WebStorm kostet glaube ich 100 Euro. Das ist dann speziell für Web-Entwicklung hervorragend. Es reicht die HTML-Features, TypeScript auch alles wunderbar. Wenn man nur TypeScript betrachten möchte, ist sehr gut, Visual Studio Code, das Code ist ganz wichtig,
58:01
auch von Microsoft, basiert auf Electron, das ist von GitHub, letztlich ein Chrome-Browser ohne Bookmarks, ohne Settings, sondern ein reiner Viewer letztlich und die haben sich da drüber einen Editor gemacht. Würde man aber nie denken, wenn man den bedient, rasend schnell und die haben exzellentes TypeScript, sogar besser.
58:21
Das ist ein Tipp und in einer Millisekunde kommen Completions, das funktioniert hervorragend. Gibt es für Linux, Depp-Pakete, RPM-Pakete, anderen Betriebssystem natürlich auch. Wenn ihr nur mal testen wollt, ist das die Empfehlung. Atom, das ist von GitHub, hat auch ein sehr gutes TypeScript Plugin. Hat aber da nichts, was in Visual Studio Code nicht auch wäre und sobald man Richtung Web-Entwicklung
58:41
geht, HTML und Code ist WebStorm dann, also die JetMains-Produkte. Eigentlich am besten. Das Fazit ist nicht so wichtig, das was hier steht. Die erste Zeit ist noch ganz nett, das ist online, kann man mit dem Code rumspielen.
59:00
Ich empfehle euch aber, wenn ihr das machen wollt, ladet euch Visual Studio Code runter, da müsst ihr sonst nichts zu haben. Der Compiler ist direkt dabei, da könnt ihr mit rumspielen. Ich denke das Wichtigste, was ich euch sagen muss, ist die letzte Zeile. Wir nutzen das jetzt bei uns seit zweieinhalb Jahren. Anfangs war das ein bisschen ungewohnt, aber ab jetzt, ich kann mir wirklich überhaupt nicht mehr vorstellen, ohne TypeScript zu arbeiten.
59:22
Die Frage war ja auch, vorhin ist das ein ECMAScript-Feature, mir ist das sogar egal, weil ich würde gar nicht auf Idee kommen, ECMAScript zu verwenden. Ich würde nur noch TypeScript benutzen wollen. Es ist eine exzellente Sprache, die den perfekten Sweet Spot für mich trifft, zwischen statisch und streng und dann doch Pragmatismus. Dann doch mein Any, weil man nun mal
59:41
Legacy, JavaScript Code oder sowas hat. Man hat nie das Gefühl, dass die Sprache cleverer ist, als man selber. Wunderbar pragmatisch. Ich kann es euch sehr empfehlen. Ich würde sagen, Punktlandung. Dann schon mal Danke für die Aufmerksamkeit.
01:00:03
Denke Puff haben wir eh, also bei Fragen kann ich natürlich noch, bleibe ich natürlich noch. Die TypeScript Features, die zuerst gekommen sind, die später beim ECMAScript auch auf der Aufzeichnung der Gastankompanie defomiert wurden. Frage war, dass es scheinbar mal Features gab, die zuerst ein TypeScript waren und dann
01:00:25
später auch ein ECMAScript kamen. Es ist tatsächlich bis jetzt immer gut gegangen, also die schauen recht weit manchmal in die Zukunft, was kommt in der übernächsten ECMAScript Version und wenn sich herausstellt, kristallisiert, dass das wohl auch kommen wird, definitiv,
01:00:42
dann bauen die das schon ein. Und der Konflikt, es steht natürlich, dass nachträglich oder sich in dieser Entwicklung noch die Spezifikation ändert, dann würde TypeScript sich überlegen, wie sehr ist das schon gesetzt, verwenden das Leute, machen wir das rückgängig, machen wir beides, bisher ist das nie ein Problem gewesen.
01:01:08
Und zwar interessiert mich die Frage, ist es intelligenter, den Code vom Editor verändern zu lassen, zum Beispiel zwei, die dann fertig verbreiten und driften,
01:01:22
ins GitHub zu pushen, oder sollte man dann nachher selber das Ganze noch mal kompilieren und dann das, was besser rauskommt? Die Frage war, best practice, glaube ich, wann ich vor allem kompiliere. Also, wenn ich eine Software ausliefer, immer nur JavaScript ausliefern,
01:01:40
also nur das Kompilat, das TypeScript spielt da gar keine Rolle mehr. In GitHub, also im Repository, liegt natürlich der ursprüngliche Source Code. Ich hoffe, ich habe die Frage da richtig verstanden. Ganz am Anfang, so früh wie möglich. Ja, nicht gerade vom Editor, man will ja auch CI haben, also irgendwie
01:02:03
Bildprozess, aber irgendeine Bildumgebung, die bei einem Entwickler läuft und dann gibt es irgendwo einen Knopf, baue mir ein Delivery und dann wird da noch mal kompiliert und JavaScript-Datamen generiert. Also es gibt immer den Knopf, dass die Editoren kompilieren, aber das ist nur zum Spielen.
01:02:21
Okay, vielen Dank.