{"id":550,"date":"2023-02-10T09:00:00","date_gmt":"2023-02-10T08:00:00","guid":{"rendered":"https:\/\/rising-bits.com\/?p=550"},"modified":"2023-02-13T17:34:07","modified_gmt":"2023-02-13T16:34:07","slug":"generics-in-typescript-teil-1","status":"publish","type":"post","link":"https:\/\/rising-bits.com\/en\/generics-in-typescript-teil-1\/","title":{"rendered":"Generics in TypeScript (Teil 1)"},"content":{"rendered":"<p>Der Schwerpunkt bei der Softwareentwicklung liegt darauf, Komponenten zu erschaffen, die nicht nur \u00fcber gut definierte und einheitliche Schnittstellen verf\u00fcgen, sondern auch wiederverwendbar sind. Komponenten, die in der Lage sind, sowohl mit aktuellen als auch zuk\u00fcnftigen Daten zu arbeiten, bieten die gr\u00f6\u00dfte Flexibilit\u00e4t beim Aufbau gro\u00dfer Software-Systeme.<\/p>\n\n\n\n<p>In Programmiersprachen wie C# und Java ist eine der wichtigsten Techniken f\u00fcr die Erstellung wiederverwendbarer Komponenten die Verwendung von Generics. Das bedeutet, dass man eine Komponente erschaffen kann, die mit verschiedenen Typen arbeiten kann, anstatt nur mit einem bestimmten Typ. Dies erm\u00f6glicht es den Anwendern, diese Komponenten zu nutzen und ihre eigenen Typen zu verwenden.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Der Einstieg in Generics<\/h2>\n\n\n\n<p>Beginnen wir mit dem Grundbeispiel der Generics: der Identit\u00e4tsfunktion. Die Identit\u00e4tsfunktion ist eine Funktion, die das zur\u00fcckgibt, was ihr \u00fcbergeben wird. Du kannst dir das vorstellen wie den Befehl <code>echo<\/code>.<\/p>\n\n\n\n<p>Ohne die Verwendung von Generics m\u00fcssten wir der Identit\u00e4tsfunktion entweder einen spezifischen Typ zuweisen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"typescript\" class=\"language-typescript\">function identity(arg: number): number {\n  return arg;\n}<\/code><\/pre>\n\n\n\n<p>Alternativ k\u00f6nnten wir die Identit\u00e4tsfunktion mit dem Typ <code>any<\/code> beschreiben:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"typescript\" class=\"language-typescript\">function identity(arg: any): any {\n  return arg;\n}<\/code><\/pre>\n\n\n\n<p>Wir haben gesehen, dass die Verwendung von <code>any<\/code> zwar generisch ist, aber bei der R\u00fcckgabe verlieren wir Informationen \u00fcber den tats\u00e4chlichen Typ. Stattdessen ben\u00f6tigen wir eine Methode, um den Typ des Arguments zu erfassen und zu definieren, was zur\u00fcckgegeben wird. Hier kommt die Typvariable ins Spiel, eine besondere Art von Variablen, die sich auf Typen und nicht auf Werte konzentriert.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"typescript\" class=\"language-typescript\">function identity&lt;Type&gt;(arg: Type): Type {\n  return arg;\n}<\/code><\/pre>\n\n\n\n<p>Wir haben eine Typvariable mit dem Namen <code>Type<\/code> zur Identit\u00e4tsfunktion hinzugef\u00fcgt. Diese Art hilft uns, den von dem Benutzer bereitgestellten Typ zu erfassen, wie zum Beispiel eine Zahl. Dadurch k\u00f6nnen wir sp\u00e4ter auf diese Information zur\u00fcckgreifen. In diesem Fall wird die Type erneut als R\u00fcckgabetyp verwendet. Wenn man genauer hinsieht, kann man erkennen, dass der gleiche Typ f\u00fcr das Argument und den R\u00fcckgabetyp verwendet wird. Dies erm\u00f6glicht es uns, diese Typ-Information auf einer Seite der Funktion einzuf\u00fchren und auf der anderen Seite wieder herauszuf\u00fchren.<\/p>\n\n\n\n<p>Wir bezeichnen diese Version der Identit\u00e4tsfunktion als generisch, da sie \u00fcber eine Vielzahl von Typen hinweg funktioniert. Im Gegensatz zur Verwendung von <code>any<\/code>, bei der manche Informationen verloren gehen k\u00f6nnen, ist diese generische Version genau so pr\u00e4zise wie die erste Identit\u00e4tsfunktion, die Zahlen f\u00fcr das Argument und den R\u00fcckgabetyp verwendet hat.<\/p>\n\n\n\n<p>Nachdem wir die generische Identit\u00e4tsfunktion geschrieben haben, kann sie auf zwei Arten aufgerufen werden. Der erste Weg besteht darin, alle Argumente, einschlie\u00dflich des Typ-Arguments, an die Funktion zu \u00fcbergeben.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"typescript\" class=\"language-typescript\">let output = identity&lt;string&gt;(\"myString\");<\/code><\/pre>\n\n\n\n<p>Hier definieren wir den <code>Type<\/code> explizit als <code>String<\/code>, indem wir eines der Argumente an die Funktion \u00fcbergeben und es mit den <code>&lt;&gt;<\/code>-Zeichen um die Argumente kennzeichnen, anstatt mit den \u00fcblichen <code>()<\/code>-Zeichen.<\/p>\n\n\n\n<p>Eine weitere M\u00f6glichkeit ist die Verwendung der Typenargument-Inferenz. Hierbei \u00fcberlassen wir dem Compiler, den Wert von Type automatisch anhand des Typs des \u00fcbergebenen Arguments zu setzen.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"typescript\" class=\"language-typescript\">let output = identity(\"myString\");<\/code><\/pre>\n\n\n\n<p>Bitte beachte, dass es nicht erforderlich war, den Typ explizit in den Winkelklammern anzugeben. Der Compiler hat einfach den Wert <code>myString<\/code> betrachtet und den Typ auf die entsprechende Art festgelegt. Trotz dessen, dass die Typargument-Inferenz ein n\u00fctzliches Mittel sein kann, um den Code k\u00fcrzer und verst\u00e4ndlicher zu gestalten, kann es in manchen F\u00e4llen notwendig sein, die Typargumente explizit anzugeben, wie dies im vorherigen Beispiel gezeigt wurde. Dies kann bei komplexeren Anwendungsf\u00e4llen der Fall sein, wenn der Compiler den Typ nicht automatisch bestimmen kann.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Das Arbeiten mit Generics<\/h2>\n\n\n\n<p>Wenn du anf\u00e4ngst, mit Generics zu arbeiten, wirst du feststellen, dass der Compiler bei der Erstellung von Funktionen wie <code>identity<\/code> daf\u00fcr sorgt, dass du die generisch typisierten Parameter innerhalb des Funktionsrumpfes korrekt verwenden. Dies bedeutet, dass du die Parameter so behandeln m\u00fcssen, als k\u00f6nnten sie jeder und jeder Typ sein. Der Compiler stellt sicher, dass du die generischen Typen korrekt in Ihrem Code verwenden.<\/p>\n\n\n\n<p>Lass uns die Identit\u00e4tsfunktion, die wir bereits kennengelernt haben, n\u00e4her betrachten:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"typescript\" class=\"language-typescript\">function identity&lt;Type&gt;(arg: Type): Type {\n  return arg;\n}<\/code><\/pre>\n\n\n\n<p>Was passiert, wenn wir bei jedem Aufruf der Funktion auch die L\u00e4nge des Arguments <code>arg<\/code> in der Konsole protokollieren m\u00f6chten? Es k\u00f6nnte verlockend sein, folgendes zu schreiben:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"typescript\" class=\"language-typescript\">function loggingIdentity&lt;Type&gt;(arg: Type): Type {\n  console.log(arg.length); \/\/ Property 'length' does not exist on type 'Type'.\n  return arg;\n}<\/code><\/pre>\n\n\n\n<p>Wenn wir den oberen Code-Block ausf\u00fchren, wird der Compiler uns einen Fehler melden, weil wir das <code>.length<\/code>-Mitglied von <code>arg<\/code> verwenden, ohne dass wir gesagt haben, dass <code>arg<\/code> dieses Mitglied hat. Wir sollten uns daran erinnern, dass wir fr\u00fcher erw\u00e4hnt haben, dass diese Typparameter f\u00fcr jeden m\u00f6glichen <code>Type<\/code> stehen und jemand, der diese Funktion nutzt, stattdessen auch eine Zahl \u00fcbergeben k\u00f6nnte, die kein <code>.length<\/code>-Mitglied hat.<\/p>\n\n\n\n<p>Angenommen, wir haben eigentlich beabsichtigt, dass diese Funktion mit Arrays des <code>Type<\/code> arbeitet und nicht direkt mit dem <code>Type<\/code>. Da wir mit <code>Arrays<\/code> arbeiten, sollte das <code>.length<\/code>-Mitglied verf\u00fcgbar sein. Wir k\u00f6nnen dies so beschreiben, wie wir <code>Arrays<\/code> anderer Typen erstellen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"typescript\" class=\"language-typescript\">function loggingIdentity&lt;Type&gt;(arg: Type[]): Type[] {\n  console.log(arg.length);\n  return arg;\n}<\/code><\/pre>\n\n\n\n<p>Der Typ von der Funktion <code>loggingIdentity<\/code> kann als &#8222;eine generische Funktion, die den Typparameter <code>Type<\/code> und ein Argument <code>arg<\/code>, welches ein <code>Array<\/code> von <code>Type<\/code>s ist, akzeptiert und ein <code>Array<\/code> von <code>Type<\/code>s zur\u00fcckgibt&#8220; gelesen werden. Wenn wir ein <code>Array<\/code> mit Zahlen \u00fcbergeben, w\u00fcrde das <code>Array<\/code> mit Zahlen zur\u00fcckgegeben, da Type an die Zahl gebunden ist. Dies gibt uns die M\u00f6glichkeit, den generischen Typparameter <code>Type<\/code> als Teil der <code>Type<\/code>s, mit denen wir arbeiten, anstelle des gesamten Typs, zu verwenden und erh\u00f6ht dadurch unsere Flexibilit\u00e4t.<\/p>\n\n\n\n<p>Alternativ k\u00f6nnen wir das Beispiel auch wie folgt schreiben:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"typescript\" class=\"language-typescript\">function loggingIdentity&lt;Type&gt;(arg: Array&lt;Type&gt;): Array&lt;Type&gt; {\n  console.log(arg.length); \/\/ Array has a .length, so no more error\n  return arg;\n}<\/code><\/pre>\n\n\n\n<p>Du kennst m\u00f6glicherweise diesen Typenstil bereits aus anderen Programmiersprachen. Im zweiten Teil dieser Reihe werden wir zeigen, wie du eigene generische Typen wie <code>Array&lt;Type&gt;<\/code> erstellen kannst.<\/p>","protected":false},"excerpt":{"rendered":"<p>Der Schwerpunkt bei der Softwareentwicklung liegt darauf, Komponenten zu erschaffen, die nicht nur \u00fcber gut definierte und einheitliche Schnittstellen verf\u00fcgen, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":553,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"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":"","adv-header-id-meta":"","stick-header-meta":"","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":""}},"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[106],"tags":[77,97,104,76],"class_list":["post-550","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-clean-code","tag-array","tag-clean-code","tag-generics","tag-typescript"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/mlmwwmq2k3up.i.optimole.com\/w:auto\/h:auto\/q:mauto\/f:best\/https:\/\/i0.wp.com\/rising-bits.com\/wp-content\/uploads\/2023\/02\/Screenshot-2023-02-13-at-17.31.35.png?fit=1668%2C684&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/rising-bits.com\/en\/wp-json\/wp\/v2\/posts\/550","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rising-bits.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rising-bits.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rising-bits.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rising-bits.com\/en\/wp-json\/wp\/v2\/comments?post=550"}],"version-history":[{"count":2,"href":"https:\/\/rising-bits.com\/en\/wp-json\/wp\/v2\/posts\/550\/revisions"}],"predecessor-version":[{"id":555,"href":"https:\/\/rising-bits.com\/en\/wp-json\/wp\/v2\/posts\/550\/revisions\/555"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rising-bits.com\/en\/wp-json\/wp\/v2\/media\/553"}],"wp:attachment":[{"href":"https:\/\/rising-bits.com\/en\/wp-json\/wp\/v2\/media?parent=550"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rising-bits.com\/en\/wp-json\/wp\/v2\/categories?post=550"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rising-bits.com\/en\/wp-json\/wp\/v2\/tags?post=550"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}