{"componentChunkName":"component---src-templates-blog-post-js","path":"/blog/ciekawostki-typescript-3-z-api-moze-przyjsc-wszystko","result":{"data":{"markdownRemark":{"html":"<p>Gdy piszemy w C# kod, który operuje na zdeserializowanym JSON-ie czujemy się pewnie: jeśli coś uda się zdeserializować do zdefiniowanego przez nas typu, to znaczy, że obiket jest poprawny i możemy normalnie na nim pracować. Początkującego programistę TyepScript może jednak zaskoczyć fakt - mimo że w zasadzie oczywisty, jeśli chwilę pomyśleć - iż jeśli \"deserializujemy\" (cudzysłowy intencjonalnie) coś w JSON-a do obiektu w TS, to możemy dostać \"pod spodem\" niepoprawne dane. Spójrzmy na przykład.</p>\n<div class=\"gatsby-highlight\" data-language=\"typescript\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-typescript line-numbers\"><code class=\"language-typescript\"><span class=\"token keyword\">const</span> json <span class=\"token operator\">=</span> <span class=\"token string\">'{ \"firstName\": 12 }'</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">interface</span> <span class=\"token class-name\">Person</span> <span class=\"token punctuation\">{</span>\n  firstName<span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">const</span> person<span class=\"token operator\">:</span> Person <span class=\"token operator\">=</span> <span class=\"token constant\">JSON</span><span class=\"token punctuation\">.</span><span class=\"token function\">parse</span><span class=\"token punctuation\">(</span>json<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token builtin\">console</span><span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">Hello, </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>person<span class=\"token punctuation\">.</span>firstName<span class=\"token punctuation\">.</span><span class=\"token function\">toUpperCase</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">;</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>Ten kod będzie poprawny w TS, ale w <em>runtime</em> wywali nam się z błędem: <code class=\"language-text\">person.firstName.toUpperCase()</code>. \"Jak to?\", pomyślicie - \"Przecież TypeScript miał sprawdzać typy!\". No, sprawdza, ale to już jest nasza odpowiedzialność, że to, co przychodzi z <code class=\"language-text\">JSON.parse</code>, chcemy traktować jako typ <code class=\"language-text\">Person</code>. Oczywiście ten przykład jest naciągany, ale łatwo w to \"wdepnąć\", np. gdy korzystamy z biblioteki do wykonywania requestów, np. <code class=\"language-text\">axios</code> - wówczas ta linijka <code class=\"language-text\">JSON.parse</code> jest ukryta przed naszymi oczyma, ale ona tam w środku jest. Jeśli więc oczekujemy, że w odpowiedzi na request dostaniemy obiekt typu <code class=\"language-text\">Person</code>, to API może - wskutek błędu - spłatać figla i wstawić <code class=\"language-text\">number</code> zamiast <code class=\"language-text\">stringa</code>. Dowiemy się o tym niestety dopiero w <em>runtime</em> i nie mamy możliwości \"deserializacji ze sprawdzeniem typu\" - bo przecież informacji o typie już w <em>runtime</em> nie mamy.</p>\n<p>Oczywiście wniosek z tego <strong>nie jest</strong> taki, żeby teraz wszystko sprawdzać: czy string jest stringiem itp. Wyczulam raczej na sytuacje w czasie developmentu, kiedy mogą nam się zdarzać rozjazdy pomiędzy deklaracjami typów, a tym, co zwraca nam np. API - zamiast wyrywać sobie włosy, zastanawiając się, dlaczego zamiast stringa mamy liczbę, sprawdźmy, czy nie jesteśmy ofiarami takiego błędnego założenia, że TS nam będzie typów strzegł także w czasie wykonywania.</p>\n<p>Ten wpis jest częścią serii o TypeScripcie, inspirowaną lekturą <a href=\"https://helion.pl/ksiazki/typescript-skuteczne-programowanie-dan-vanderkam,e_1lgp.htm\">książki D. Vanderkama pt. \"TypeScript. Skuteczne programowanie\"</a>.</p>","excerpt":"Gdy piszemy w C# kod, który operuje na zdeserializowanym JSON-ie czujemy się pewnie: jeśli coś uda się zdeserializować do zdefiniowanego przez nas typu, to…","frontmatter":{"date":"14 October, 2020","path":"/blog/ciekawostki-typescript-3-z-api-moze-przyjsc-wszystko","title":"Ciekawostki Typescript #3 - z API może przyjść wszystko"},"fields":{"readingTime":{"text":"2 min read"}}}},"pageContext":{}},"staticQueryHashes":["3649515864","63159454"]}