{"componentChunkName":"component---src-templates-blog-post-js","path":"/blog/ciekawostki-typescript-1-typ-vs-interfejs","result":{"data":{"markdownRemark":{"html":"<p>W TypeScripcie mamy do dyspozycji dwa podobne byty, które przy deklarowaniu typów wydają się być zamienne - <code class=\"language-text\">type</code> oraz <code class=\"language-text\">interface</code>. Czy te dwa typy czymś się różnią?</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\">type</span> <span class=\"token class-name\">Person1</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  name<span class=\"token operator\">:</span> <span class=\"token builtin\">string</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">interface</span> <span class=\"token class-name\">Person2</span> <span class=\"token punctuation\">{</span>\n  name<span class=\"token operator\">:</span> <span class=\"token builtin\">string</span>\n<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></pre></div>\n<p>W ogólności, poza subtelną różnicą w składni - do <code class=\"language-text\">type</code> \"przypisujemy\" deklarację, a <code class=\"language-text\">interface</code> deklarujemy wprost, bez znaku <code class=\"language-text\">=</code> - te dwie konstrukcje można stosować zamiennie. Obie będą weryfikować typ, np.:</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> alice<span class=\"token operator\">:</span> Person1 <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  name<span class=\"token operator\">:</span> <span class=\"token string\">\"Alice\"</span><span class=\"token punctuation\">,</span>\n  age<span class=\"token operator\">:</span> <span class=\"token number\">20</span><span class=\"token punctuation\">,</span>\n  <span class=\"token comment\">// -> tu będzie błąd</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">const</span> bob<span class=\"token operator\">:</span> Person1 <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  name<span class=\"token operator\">:</span> <span class=\"token string\">\"Bob\"</span><span class=\"token punctuation\">,</span>\n  age<span class=\"token operator\">:</span> <span class=\"token number\">25</span><span class=\"token punctuation\">,</span>\n  <span class=\"token comment\">// -> tu będzie błąd</span>\n<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></span><span></span><span></span></span></pre></div>\n<p>Obie konstrukcje możemy też używać zamiennie w bardziej złożonych przykładach, jak sygnatury indeksu czy typy funkcji, np.:</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\">type</span> <span class=\"token class-name\">Dictionary1</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> <span class=\"token punctuation\">[</span>key<span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">]</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span> <span class=\"token punctuation\">}</span>\n<span class=\"token keyword\">interface</span> <span class=\"token class-name\">Dictionary2</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token punctuation\">[</span>key<span class=\"token operator\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">]</span><span class=\"token operator\">:</span> <span class=\"token builtin\">string</span>\n<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></pre></div>\n<p>Zarówno typ, jak i interfejs możemy \"podziedziczyć\" (właściwe określenie w świecie TS to raczej - rozszerzyć):</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\">class</span> <span class=\"token class-name\">Employee1</span> <span class=\"token keyword\">implements</span> <span class=\"token class-name\">Person1</span> <span class=\"token punctuation\">{</span>\n  name<span class=\"token operator\">:</span> <span class=\"token builtin\">string</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">Employee2</span> <span class=\"token keyword\">implements</span> <span class=\"token class-name\">Person2</span> <span class=\"token punctuation\">{</span>\n  name<span class=\"token operator\">:</span> <span class=\"token builtin\">string</span>\n<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></pre></div>\n<p>Jakie zatem mamy różnice?</p>\n<ol>\n<li>Jeśli definiujemy unię, to możemy zastosować tylko tylko <code class=\"language-text\">type</code>: <code class=\"language-text\">type State = 'on' | 'off'</code></li>\n<li>Tylko <code class=\"language-text\">type</code> może rozszerzać unię: <code class=\"language-text\">type StateExtended = State &amp; 'paused'</code></li>\n<li>Teoretycznie interfejsem można wyrazić krotkę, ale za pomocą typu jest to dużo bardziej czytelne i naturalne:</li>\n</ol>\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\">type</span> <span class=\"token class-name\">Pair</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token builtin\">number</span><span class=\"token punctuation\">,</span> <span class=\"token builtin\">number</span><span class=\"token punctuation\">]</span>\n\n<span class=\"token comment\">// zamiast jakiegoś dziwadła</span>\n\n<span class=\"token keyword\">interface</span> <span class=\"token class-name\">Tuple</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token number\">0</span><span class=\"token operator\">:</span> <span class=\"token builtin\">number</span>\n  <span class=\"token number\">1</span><span class=\"token operator\">:</span> <span class=\"token builtin\">number</span>\n  length<span class=\"token operator\">:</span> <span class=\"token number\">2</span>\n<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></span></span></pre></div>\n<ol start=\"4\">\n<li>Z drugiej strony <code class=\"language-text\">interface</code> umożliwia <em>scalanie deklaracji</em>, czyli coś w stylu <code class=\"language-text\">partial class</code> z C#. Chodzi o to, że możemy w jednym pliku zadeklarować interfejs, a w innym - \"dalszą jego część\", finalnie uzyskując interfejs, który będzie połączeniem obydwu deklaracji, np.:</li>\n</ol>\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 comment\">// plik Person.ts</span>\n<span class=\"token keyword\">interface</span> <span class=\"token class-name\">Person</span> <span class=\"token punctuation\">{</span>\n  name<span class=\"token operator\">:</span> <span class=\"token builtin\">string</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token comment\">// plik PersonAddress.ts</span>\n<span class=\"token keyword\">interface</span> <span class=\"token class-name\">Person</span> <span class=\"token punctuation\">{</span>\n  address<span class=\"token operator\">:</span> <span class=\"token builtin\">string</span>\n<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></span></span></pre></div>\n<p>Ten myk nie jest potrzebny raczej w naszym kodzie (możemy przecież scalić deklaracje do jednego pliku), ale przydaje się, gdy chcemy zmodyfikować typ, który dostajemy z jakiejś zewnętrznej biblioteki. Ten mechanizm wykorzystuje też podstawowa biblioteka TS - nowości i zmiany w kolejnych standardach ES to kolejne pliki, które rozszerzają wcześniejsze deklaracje: zatem wybierając odpowiedni standard ES, <em>de facto</em> wybieramy zestaw plików z deklaracjami, które są scalane.</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":"W TypeScripcie mamy do dyspozycji dwa podobne byty, które przy deklarowaniu typów wydają się być zamienne -  oraz . Czy te dwa typy czymś się różnią? W…","frontmatter":{"date":"01 September, 2020","path":"/blog/ciekawostki-typescript-1-typ-vs-interfejs","title":"Ciekawostki Typescript #1 - typ vs. interfejs"},"fields":{"readingTime":{"text":"2 min read"}}}},"pageContext":{}},"staticQueryHashes":["3649515864","63159454"]}