{"id":21454,"date":"2025-09-03T10:00:03","date_gmt":"2025-09-03T15:00:03","guid":{"rendered":"http:\/\/carterembry.com\/?p=21454"},"modified":"2025-09-03T11:27:37","modified_gmt":"2025-09-03T16:27:37","slug":"adopting-typescript-at-scale","status":"publish","type":"post","link":"https:\/\/carterembry.com\/de\/2025\/adopting-typescript-at-scale\/%20","title":{"rendered":"Die Einf\u00fchrung von TypeScript im gro\u00dfen Ma\u00dfstab (oder der Radwechsel an einem fahrenden Bus)"},"content":{"rendered":"<div id=\"pl-21454\"  class=\"panel-layout\" ><div id=\"pg-21454-0\"  class=\"panel-grid panel-no-style\" ><div id=\"pgc-21454-0-0\"  class=\"panel-grid-cell\" ><div id=\"panel-21454-0-0-0\" class=\"so-panel widget widget_sow-editor panel-first-child panel-last-child\" data-index=\"0\" ><div\n\t\t\t\n\t\t\tclass=\"so-widget-sow-editor so-widget-sow-editor-base\"\n\t\t\t\n\t\t>\n<div class=\"siteorigin-widget-tinymce textwidget\">\n\t<p>Hallo Freunde! Ich bin's, Daniel.<\/p>\n<p>Wenn du mich im wirklichen Leben kennst, hast du wahrscheinlich schon einmal geh\u00f6rt, wie ich ausf\u00fchrlich \u00fcber JavaScript geredet habe. Mein erster professioneller Programmierjob bestand fast ausschlie\u00dflich aus Vanilla JavaScript, deshalb liebe ich JS schon seit langem. Im Gegensatz zu anderen finde ich seine Macken und Exzentrizit\u00e4ten liebenswert. Die prototypische Vererbung ist anfangs ein bisschen verr\u00fcckt, aber f\u00fcr den t\u00e4glichen Gebrauch ist sie eigentlich ziemlich einfach. Ich habe schon viele Modeerscheinungen kommen und gehen sehen (ich schaue dich an, Coffeescript). Trotzdem hat es lange gedauert, bis ich auf den Typescript-Zug aufgesprungen bin. Aber jetzt, wo ich hier bin? Ich bin <strong>ALL IN<\/strong>.<\/p>\n<\/div>\n<\/div><\/div><\/div><\/div><div id=\"pg-21454-1\"  class=\"panel-grid panel-no-style\" ><div id=\"pgc-21454-1-0\"  class=\"panel-grid-cell\" ><div id=\"panel-21454-1-0-0\" class=\"so-panel widget widget_sow-editor panel-first-child panel-last-child\" data-index=\"1\" ><div\n\t\t\t\n\t\t\tclass=\"so-widget-sow-editor so-widget-sow-editor-base\"\n\t\t\t\n\t\t>\n<div class=\"siteorigin-widget-tinymce textwidget\">\n\t<p>I <em>Liebe<\/em> Typescript. Du kannst klar verst\u00e4ndliche Vertr\u00e4ge f\u00fcr deine Datenstrukturen, Funktionen und Klassen festlegen und sie zur Kompilierzeit durchsetzen. Das hei\u00dft, wenn jemand etwas missbraucht oder einen Vertrag\/eine Schnittstelle \u00e4ndert, wird das bemerkt. <strong>vor<\/strong> und deine Nutzerinnen und Nutzer zu verletzen. <em>Es ist ein Code, der erkl\u00e4rt, wie er verwendet werden soll.<\/em> Was gibt es daran nicht zu lieben? Ich habe bereits auf diese Weise \u00fcber JS nachgedacht, warum sollte ich nicht noch eine Ebene hinzuf\u00fcgen, um meine Gedanken zu erkl\u00e4ren? Das eignet sich hervorragend f\u00fcr Teams oder funktions\u00fcbergreifende Aufgaben, aber auch f\u00fcr die Zukunft (nachdem ich geschlafen und alles vergessen habe).<\/p>\n<p>Wir verwenden Typescript in meinem Job<span class=\"BxUVEf ILfuVd\" lang=\"en\"><span class=\"hgKElc\">\u2122 aber das war nicht immer so. Ich arbeite in einer Anwendung, die <strong>mumble-mumble<\/strong> Jahren mit vielen Code-Generationen - von den Tagen des klassenbasierten React mit Redux+Thunks bis hin zu moderneren funktionalen Komponenten auf Basis von React Hooks. Es ist, als w\u00fcrde man sich durch felsige Sedimentschichten w\u00fchlen, um das historische Warum und Wie freizulegen. Alles Neue ist in Typescript geschrieben und das f\u00fchlt sich gro\u00dfartig an - aber es war nicht hilfreich, wenn wir uns in \u00e4ltere Funktionen vertiefen mussten (oder *gasp* Schulden bereinigen). Als wir merkten, wie viel Spa\u00df es macht, unsere neuen Komponenten zu nutzen (und wie weh es tut, die alten zu benutzen), wollte ich schneller ans Ziel kommen. Ich wollte in der Zukunft leben, nicht in der Vergangenheit.<\/span><\/span><\/p>\n<h3>Enter <a href=\"https:\/\/github.com\/airbnb\/ts-migrate\">AirBnBs erstaunlich praktisches Tool, ts-migrate.<\/a><\/h3>\n<\/div>\n<\/div><\/div><\/div><div id=\"pgc-21454-1-1\"  class=\"panel-grid-cell\" ><div id=\"panel-21454-1-1-0\" class=\"so-panel widget widget_sow-image panel-first-child\" data-index=\"2\" ><div\n\t\t\t\n\t\t\tclass=\"so-widget-sow-image so-widget-sow-image-default-8b5b6f678277-21454\"\n\t\t\t\n\t\t>\n<div class=\"sow-image-container\">\n\t\t<img \n\tsrc=\"https:\/\/carterembry.com\/wp-content\/uploads\/2025\/08\/typescript_over_javascript.jpg\" width=\"750\" height=\"500\" srcset=\"https:\/\/carterembry.com\/wp-content\/uploads\/2025\/08\/typescript_over_javascript.jpg 750w, https:\/\/carterembry.com\/wp-content\/uploads\/2025\/08\/typescript_over_javascript-200x133.jpg 200w, https:\/\/carterembry.com\/wp-content\/uploads\/2025\/08\/typescript_over_javascript-18x12.jpg 18w, https:\/\/carterembry.com\/wp-content\/uploads\/2025\/08\/typescript_over_javascript-272x182.jpg 272w, https:\/\/carterembry.com\/wp-content\/uploads\/2025\/08\/typescript_over_javascript-720x480.jpg 720w\" sizes=\"(max-width: 750px) 100vw, 750px\" alt=\"Meme von einem Paar, das zusammen spazieren geht. Seine Lebensgef\u00e4hrtin hat &quot;Javascript&quot; \u00fcber sich geschrieben, w\u00e4hrend die andere Frau &quot;Typescript&quot; \u00fcber sich geschrieben hat. Der Mann schaut \u00fcber seine Schulter zu der anderen Frau (Typescript) und zeigt damit, dass sie seine Aufmerksamkeit erregt hat.\" \t\tclass=\"so-widget-image\" loading=\"lazy\" \/>\n\t<\/div>\n\n<\/div><\/div><div id=\"panel-21454-1-1-1\" class=\"so-panel widget widget_sow-editor panel-last-child\" data-index=\"3\" ><div\n\t\t\t\n\t\t\tclass=\"so-widget-sow-editor so-widget-sow-editor-base\"\n\t\t\t\n\t\t>\n<div class=\"siteorigin-widget-tinymce textwidget\">\n\t<blockquote class=\"quote\">\n<p>Ich wollte schneller ankommen. Ich wollte in der Zukunft leben, nicht in der Vergangenheit.<\/p>\n<\/blockquote>\n<\/div>\n<\/div><\/div><\/div><\/div><div id=\"pg-21454-2\"  class=\"panel-grid panel-no-style\" ><div id=\"pgc-21454-2-0\"  class=\"panel-grid-cell\" ><div id=\"panel-21454-2-0-0\" class=\"so-panel widget widget_sow-editor panel-first-child panel-last-child\" data-index=\"4\" ><div class=\"panel-widget-style panel-widget-style-for-21454-2-0-0\" ><div\n\t\t\t\n\t\t\tclass=\"so-widget-sow-editor so-widget-sow-editor-base\"\n\t\t\t\n\t\t>\n<div class=\"siteorigin-widget-tinymce textwidget\">\n\t<p>Dieses tolle Tool durchl\u00e4uft deine gesamte Codebasis und konvertiert alle <strong>.js(x)<\/strong> Dateien zu\u00a0<strong>.ts(x)<\/strong>.<\/p>\n<p>Ich wei\u00df, ich wei\u00df, das f\u00fchlt sich schmutzig an. Es verwendet standardm\u00e4\u00dfig das gef\u00fcrchtete <strong>jede<\/strong> Datentyp, <a href=\"https:\/\/www.allthingstypescript.dev\/p\/why-avoid-the-any-type-in-typescript\">was ein bevorzugtes Verbot ist<\/a>. An Stellen, an denen es nicht wei\u00df, wie die Typen zusammenwirken sollen, f\u00fcgt es einen Kommentar ein, der Typescript anweist, die n\u00e4chste Zeile zu ignorieren. Ich wei\u00df, ich wei\u00df, das f\u00fchlt sich nicht weniger schmutzig an.<\/p>\n<p>ABER h\u00f6r zu. Diese JS-Dateien verhalten sich bereits im Wesentlichen auf diese Weise. Es gibt keine Typen, also ist alles bereits ein <strong>jeder.<\/strong><\/p>\n<p>&nbsp;<\/p>\n<\/div>\n<\/div><\/div><\/div><\/div><\/div><div id=\"pg-21454-3\"  class=\"panel-grid panel-has-style\" ><div class=\"panel-row-style panel-row-style-for-21454-3\" ><div id=\"pgc-21454-3-0\"  class=\"panel-grid-cell\" ><div id=\"panel-21454-3-0-0\" class=\"so-panel widget widget_sow-editor panel-first-child panel-last-child\" data-index=\"5\" ><div class=\"panel-widget-style panel-widget-style-for-21454-3-0-0\" ><div\n\t\t\t\n\t\t\tclass=\"so-widget-sow-editor so-widget-sow-editor-base\"\n\t\t\t\n\t\t>\n<div class=\"siteorigin-widget-tinymce textwidget\">\n\t<h3>Ungeachtet des Ekels hat dies mindestens zwei unmittelbare strategische Vorteile:<\/h3>\n<ol>\n<li style=\"text-align: left;\">Das Einbinden neuer Komponenten in alte Komponenten ist jetzt typsicher. Vor dieser \u00c4nderung h\u00e4tten sie genauso gut normales JS sein k\u00f6nnen, wenn wir sie in alten Code einbauen mussten.\n<ul>\n<li>Das bedeutet, dass unser neuer Typescript-Code jetzt die Qualit\u00e4t der alten Dateien anhebt, anstatt dass die alten Dateien die gesamte Codebasis herunterziehen.<\/li>\n<\/ul>\n<\/li>\n<li>Jede einzelne Stelle, die beachtet werden muss, um wirklich Typescript-f\u00e4hig zu sein, ist nun mit einem Kommentar oder einem <strong>jede<\/strong> Datentyp. Wir versuchen, jede alte Datei zu bereinigen, die angefasst wird, eine nach der anderen. Das Aufz\u00e4hlen des Umfangs eines Problems kann selbst zeitaufw\u00e4ndig sein - bei diesem Ansatz ist es schon erledigt.<\/li>\n<\/ol>\n<\/div>\n<\/div><\/div><\/div><\/div><div id=\"pgc-21454-3-1\"  class=\"panel-grid-cell\" ><div id=\"panel-21454-3-1-0\" class=\"so-panel widget widget_sow-editor panel-first-child panel-last-child\" data-index=\"6\" ><div\n\t\t\t\n\t\t\tclass=\"so-widget-sow-editor so-widget-sow-editor-base\"\n\t\t\t\n\t\t>\n<div class=\"siteorigin-widget-tinymce textwidget\">\n\t<blockquote class=\"quote\"><p>Es ist ein Code, der erkl\u00e4rt, wie er verwendet werden soll. Was kann man daran nicht m\u00f6gen?<\/p><\/blockquote>\n<\/div>\n<\/div><\/div><\/div><\/div><\/div><div id=\"pg-21454-4\"  class=\"panel-grid panel-has-style\" ><div class=\"panel-row-style panel-row-style-for-21454-4\" ><div id=\"pgc-21454-4-0\"  class=\"panel-grid-cell\" ><div id=\"panel-21454-4-0-0\" class=\"so-panel widget widget_sow-editor panel-first-child panel-last-child\" data-index=\"7\" ><div\n\t\t\t\n\t\t\tclass=\"so-widget-sow-editor so-widget-sow-editor-base\"\n\t\t\t\n\t\t>\n<div class=\"siteorigin-widget-tinymce textwidget\">\n\t<p>Ich wei\u00df, dass einige von euch dieses \"schmutzige\" Gef\u00fchl noch nicht losgeworden sind, aber ich sage euch. <strong>wird dein Leben besser sein.<\/strong> Unseres ist definitiv besser. Wir konnten JS-Dateien verbieten und so die \u00dcbernahme weiter erzwingen. Wir haben eine klare Auflistung unserer verbleibenden JS-Schulden. Und das Aufr\u00e4umen alter Dateien ist nicht mehr ein un\u00fcberwindbares Chaos, sondern ein einfacher Zusatz zur bestehenden Arbeit.<\/p>\n<p>Die positiven Vorteile \u00fcberwiegen bei weitem die Bedenken wegen der Unordnung, die durch einen automatisierten Prozess entsteht. Das war uns nicht klar, bevor wir es eingesetzt haben, aber im Nachhinein ist es glasklar. Ist es das nicht immer?<\/p>\n<p>Nimm die Zukunft an - es dauert nur eine Weile und du wirst es nicht bereuen.<\/p>\n<\/div>\n<\/div><\/div><\/div><\/div><\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>Hallo Freunde! Ich bin's, Daniel. Wenn du mich im wirklichen Leben kennst, hast du wahrscheinlich schon einmal geh\u00f6rt, wie ich ausf\u00fchrlich \u00fcber JavaScript geredet habe. Bei meinem ersten professionellen Programmierjob habe ich fast ausschlie\u00dflich mit Vanilla JavaScript gearbeitet, deshalb liebe ich JS schon lange. Im Gegensatz zu anderen finde ich seine Macken und Exzentrizit\u00e4ten liebenswert. Prototypische Vererbung ist ein bisschen verr\u00fcckt [...]<\/p>","protected":false},"author":3,"featured_media":21459,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"wprm-recipe-roundup-name":"","wprm-recipe-roundup-description":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"default","adv-header-id-meta":"","stick-header-meta":"default","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[10,5,7],"tags":[],"class_list":["post-21454","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-about-daniel","category-professional-opinions","category-technical-jargon"],"_links":{"self":[{"href":"https:\/\/carterembry.com\/de\/wp-json\/wp\/v2\/posts\/21454","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/carterembry.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/carterembry.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/carterembry.com\/de\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/carterembry.com\/de\/wp-json\/wp\/v2\/comments?post=21454"}],"version-history":[{"count":24,"href":"https:\/\/carterembry.com\/de\/wp-json\/wp\/v2\/posts\/21454\/revisions"}],"predecessor-version":[{"id":21482,"href":"https:\/\/carterembry.com\/de\/wp-json\/wp\/v2\/posts\/21454\/revisions\/21482"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/carterembry.com\/de\/wp-json\/wp\/v2\/media\/21459"}],"wp:attachment":[{"href":"https:\/\/carterembry.com\/de\/wp-json\/wp\/v2\/media?parent=21454"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/carterembry.com\/de\/wp-json\/wp\/v2\/categories?post=21454"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/carterembry.com\/de\/wp-json\/wp\/v2\/tags?post=21454"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}