{"componentChunkName":"component---src-templates-blog-post-js","path":"/typescript-interface-x-type-alias/","result":{"data":{"site":{"siteMetadata":{"siteUrl":"https://guilhermeramos.dev"}},"markdownRemark":{"fields":{"slug":"/typescript-interface-x-type-alias/"},"frontmatter":{"category":"Typescript","date":"27 de novembro, 2020","thumbnail":"assets/img/captura-de-tela-2020-11-30-às-09.41.41-1-.jpg","title":"Typescript: Interface x Type alias","description":"Sabe a diferença entre type aliases e interfaces? Na prática, eles parecem ser a mesma coisa, mas existem algumas diferenças bem pontuais entre um e outro."},"html":"<p>No último final de semana, eu peguei o <a href=\"https://youtu.be/mRixno_uE2o\">mini-curso de Typescript do Willian Justen</a> e, apesar de já usar typescript no meu dia a dia, achei bem legal para entender um pouco melhor algumas coisas que não peguei aprendendo na prática, ou entender melhor algumas práticas que eu usava mas não entendia muito a fundo a razão de usar. Além de ser gratuito, no YouTube, é bem curto (15 aulas). Recomendo, com certeza, para qualquer um que queira aprender a tecnologia ou entender um pouco melhor.</p>\n<p>Porém, durante o curso, lembrei de uma dúvida que eu já havia tido antes: <strong>qual a diferença entre type aliases e interfaces</strong>?</p>\n<p>Na prática, eles parecem ser a mesma coisa: apesar da sintaxe diferente, você pode usar ambos para declarar objetos, pode implementá-los em classes e pode até rolar uma herança ali, entre eles. Então, tanto faz usar um ou outro?</p>\n<p>A resposta é: claro que não.</p>\n<p>Existem diferenças e casos de uso para ambos (apesar de que, na prática, na maioria dos casos, você realmente pode usar tanto um quanto outro).</p>\n<p>Mas vamos lá entender um pouco melhor isso:</p>\n<h2>Antes de mais nada, o que são type aliases e interfaces</h2>\n<p>Nada mais são do que formas de tipar constantes ou objetos dentro do typescript.</p>\n<p>As interfaces são usadas para, somente, descrever objetos, como é visto no exemplo a seguir:</p>\n<div class=\"gatsby-highlight\" data-language=\"typescript\"><pre class=\"language-typescript\"><code class=\"language-typescript\"><span class=\"token keyword\">interface</span> <span class=\"token class-name\">Table</span> <span class=\"token punctuation\">{</span>\n\twidth<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span>\n\theight<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span>\n\tlength<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span>\n\tcolor<span class=\"token punctuation\">:</span> <span class=\"token string\">\"Black\"</span> <span class=\"token operator\">|</span> <span class=\"token string\">\"White\"</span> <span class=\"token operator\">|</span> <span class=\"token string\">\"Brown\"</span>\n\tnumberOfDrawers<span class=\"token punctuation\">:</span> <span class=\"token number\">4</span> <span class=\"token operator\">|</span> <span class=\"token number\">6</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Já um type alias é usado para declarar tipos, de modo geral, seja um tipo primitivo, união ou, também, um objeto:</p>\n<div class=\"gatsby-highlight\" data-language=\"typescript\"><pre class=\"language-typescript\"><code class=\"language-typescript\"><span class=\"token keyword\">type</span> Height <span class=\"token operator\">=</span> <span class=\"token builtin\">number</span>\n\n<span class=\"token keyword\">type</span> Width <span class=\"token operator\">=</span> <span class=\"token builtin\">number</span>\n\n<span class=\"token keyword\">type</span> Size <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n\twidth<span class=\"token punctuation\">:</span> Width\n\theight<span class=\"token punctuation\">:</span> Height\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">type</span> Color <span class=\"token operator\">=</span> <span class=\"token string\">\"Black\"</span> <span class=\"token operator\">|</span> <span class=\"token string\">\"White\"</span> <span class=\"token operator\">|</span> <span class=\"token string\">\"Brown\"</span>\n\n<span class=\"token keyword\">type</span> Table <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n\tsize<span class=\"token punctuation\">:</span> Size\n\tcolor<span class=\"token punctuation\">:</span> Color\n\tnumberOfDrawers<span class=\"token punctuation\">:</span> <span class=\"token number\">4</span> <span class=\"token operator\">|</span> <span class=\"token number\">6</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Essa é a diferença mais marcante. Porém, se fosse a única, eu poderia usar type aliases para declarar qualquer tipo, e tava tudo bem, não é mesmo? Na verdade, não precisaria nem de interfaces, já que um type alias também serve para objetos.</p>\n<p>Porém, as diferenças vão um pouquinho mais além do que isso. Então, listei abaixo algumas semelhanças e diferenças que encontrei, para ficar um pouco mais claro essa diferenciação:</p>\n<h3>Semelhança: Objectos e funções</h3>\n<p>Realmente, tanto interfaces quanto type aliases podem ser usados para descrever objectos e funções...</p>\n<div class=\"gatsby-highlight\" data-language=\"typescript\"><pre class=\"language-typescript\"><code class=\"language-typescript\"><span class=\"token keyword\">type</span> PersonType <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n    name<span class=\"token punctuation\">:</span> <span class=\"token builtin\">string</span>\n    age<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span>\n    walk<span class=\"token operator\">?</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">steps<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token keyword\">void</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">interface</span> <span class=\"token class-name\">IPerson</span> <span class=\"token punctuation\">{</span>\n    name<span class=\"token punctuation\">:</span> <span class=\"token builtin\">string</span>\n    age<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span>\n    walk<span class=\"token operator\">?</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">steps<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token keyword\">void</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h3>Diferença: Tipos simples</h3>\n<p>... Porém, diferente de uma interface, o type alias também pode ser usado para definir tipos simples, como number, string, tuple, union, etc</p>\n<div class=\"gatsby-highlight\" data-language=\"typescript\"><pre class=\"language-typescript\"><code class=\"language-typescript\"><span class=\"token comment\">// String</span>\n<span class=\"token keyword\">type</span> Name <span class=\"token operator\">=</span> <span class=\"token builtin\">string</span>\n<span class=\"token keyword\">const</span> myName<span class=\"token punctuation\">:</span> Name <span class=\"token operator\">=</span> <span class=\"token string\">'Guilherme'</span>\n\n<span class=\"token comment\">// Number</span>\n<span class=\"token keyword\">type</span> Age <span class=\"token operator\">=</span> <span class=\"token builtin\">number</span>\n<span class=\"token keyword\">const</span> myAge<span class=\"token punctuation\">:</span> Age <span class=\"token operator\">=</span> <span class=\"token number\">22</span>\n\n<span class=\"token comment\">// Union</span>\n<span class=\"token keyword\">type</span> PartialPointX <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> x<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span> <span class=\"token punctuation\">}</span>\n<span class=\"token keyword\">type</span> PartialPointY <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> y<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span> <span class=\"token punctuation\">}</span>\n<span class=\"token keyword\">type</span> PartialPoint <span class=\"token operator\">=</span> PartialPointX <span class=\"token operator\">|</span> PartialPointY\n\n<span class=\"token comment\">// Tuple</span>\n<span class=\"token keyword\">type</span> Data <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<span class=\"token keyword\">const</span> anyData<span class=\"token punctuation\">:</span> Data <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span> <span class=\"token number\">5</span><span class=\"token punctuation\">,</span> <span class=\"token number\">10</span> <span class=\"token punctuation\">]</span></code></pre></div>\n<h3>Diferença: Diferentes interfaces com mesmo nome</h3>\n<p>Já a interface, quando você define várias com o mesmo nome, o typescript mescla todas elas em uma só, com todas as especificações (o que não acontece com type alias).</p>\n<div class=\"gatsby-highlight\" data-language=\"typescript\"><pre class=\"language-typescript\"><code class=\"language-typescript\"><span class=\"token keyword\">interface</span> <span class=\"token class-name\">IPoint</span> <span class=\"token punctuation\">{</span>\n    y<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">interface</span> <span class=\"token class-name\">IPoint</span> <span class=\"token punctuation\">{</span>\n    x<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">const</span> <span class=\"token function-variable function\">getRectangleAreaInterface</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span>x<span class=\"token punctuation\">,</span>y<span class=\"token punctuation\">}</span><span class=\"token punctuation\">:</span> IPoint</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token builtin\">console</span><span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span>x <span class=\"token operator\">*</span> y<span class=\"token punctuation\">)</span>\n<span class=\"token function\">getRectangleAreaInterface</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>x<span class=\"token punctuation\">:</span> <span class=\"token number\">2</span><span class=\"token punctuation\">,</span> y<span class=\"token punctuation\">:</span> <span class=\"token number\">10</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span> <span class=\"token comment\">// 20</span></code></pre></div>\n<p>Perceba que, na declaração do <code class=\"language-text\">getRectangleAreaInterface</code>, o <em>IPoint</em> leva em consideração tanto o y quanto o x.</p>\n<h3>Semelhança: Herança</h3>\n<p>É possível ocorrer herança tanto entre type aliases e interfaces quanto entre ambos os tipos. Além disso, ambas também podem ser herdadas por classes.</p>\n<div class=\"gatsby-highlight\" data-language=\"typescript\"><pre class=\"language-typescript\"><code class=\"language-typescript\"><span class=\"token comment\">// Interface herda interface</span>\n<span class=\"token keyword\">interface</span> <span class=\"token class-name\">Person</span> <span class=\"token punctuation\">{</span> name<span class=\"token punctuation\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">,</span> age<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span> <span class=\"token punctuation\">}</span>\n<span class=\"token keyword\">interface</span> <span class=\"token class-name\">Human</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">Person</span> <span class=\"token punctuation\">{</span> <span class=\"token function-variable function\">walk</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">steps<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token keyword\">void</span> <span class=\"token punctuation\">}</span>\n\n<span class=\"token comment\">// Interface herda type alias</span>\n<span class=\"token keyword\">type</span> Person <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> name<span class=\"token punctuation\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">,</span> age<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span> <span class=\"token punctuation\">}</span>\n<span class=\"token keyword\">interface</span> <span class=\"token class-name\">Human</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">Person</span> <span class=\"token punctuation\">{</span> <span class=\"token function-variable function\">walk</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">steps<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token keyword\">void</span> <span class=\"token punctuation\">}</span>\n\n<span class=\"token comment\">// Type alias herda type alias</span>\n<span class=\"token keyword\">type</span> Person <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> name<span class=\"token punctuation\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">,</span> age<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span> <span class=\"token punctuation\">}</span>\n<span class=\"token keyword\">type</span> Human <span class=\"token operator\">=</span> Person <span class=\"token operator\">&amp;</span> <span class=\"token punctuation\">{</span> <span class=\"token function-variable function\">walk</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">steps<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token keyword\">void</span> <span class=\"token punctuation\">}</span>\n\n<span class=\"token comment\">// Type alis herda interface</span>\n<span class=\"token keyword\">interface</span> <span class=\"token class-name\">Person</span> <span class=\"token punctuation\">{</span> name<span class=\"token punctuation\">:</span> <span class=\"token builtin\">string</span><span class=\"token punctuation\">,</span> age<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span> <span class=\"token punctuation\">}</span>\n<span class=\"token keyword\">type</span> Human <span class=\"token operator\">=</span> Person <span class=\"token operator\">&amp;</span> <span class=\"token punctuation\">{</span> <span class=\"token function-variable function\">walk</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">steps<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token keyword\">void</span> <span class=\"token punctuation\">}</span></code></pre></div>\n<p><em>Obs.: Há diferentes interfaces e tipos com o mesmo nome para fins didáticos. No código, foi preciso deixar cada um em um escopo isolado.</em></p>\n<h3>Semelhança: Implementando uma interface ou type alias em uma classe</h3>\n<p>Uma classe pode implementar tanto uma interface quando um type alias, e a sintaxe é a mesma para ambos os casos.</p>\n<p><strong>Implementando uma interface:</strong></p>\n<div class=\"gatsby-highlight\" data-language=\"typescript\"><pre class=\"language-typescript\"><code class=\"language-typescript\"><span class=\"token keyword\">interface</span> <span class=\"token class-name\">PolygonSides</span> <span class=\"token punctuation\">{</span>\n    x<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span>\n    y<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">Square</span> <span class=\"token keyword\">implements</span> <span class=\"token class-name\">PolygonSides</span> <span class=\"token punctuation\">{</span>\n    x<span class=\"token punctuation\">:</span> <span class=\"token number\">4</span>\n    y<span class=\"token punctuation\">:</span> <span class=\"token number\">20</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><strong>Implementando um type alias:</strong></p>\n<div class=\"gatsby-highlight\" data-language=\"typescript\"><pre class=\"language-typescript\"><code class=\"language-typescript\"><span class=\"token keyword\">type</span> PolygonSides <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n    x<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span>\n    y<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">Square</span> <span class=\"token keyword\">implements</span> <span class=\"token class-name\">PolygonSides</span> <span class=\"token punctuation\">{</span>\n    x<span class=\"token punctuation\">:</span> <span class=\"token number\">4</span>\n    y<span class=\"token punctuation\">:</span> <span class=\"token number\">20</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Porém, não é possível implementar um type alias se ele for resultado de uma união:</p>\n<div class=\"gatsby-highlight\" data-language=\"typescript\"><pre class=\"language-typescript\"><code class=\"language-typescript\"><span class=\"token keyword\">type</span> SideX <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> x<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span> <span class=\"token punctuation\">}</span>\n<span class=\"token keyword\">type</span> SideY <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> y<span class=\"token punctuation\">:</span> <span class=\"token builtin\">number</span> <span class=\"token punctuation\">}</span>\n<span class=\"token keyword\">type</span> PolygonSides <span class=\"token operator\">=</span> SideX <span class=\"token operator\">|</span> SideY\n\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">Square</span> <span class=\"token keyword\">implements</span> <span class=\"token class-name\">PolygonSides</span> <span class=\"token punctuation\">{</span>\n    x<span class=\"token punctuation\">:</span> <span class=\"token number\">4</span>\n    y<span class=\"token punctuation\">:</span> <span class=\"token number\">20</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>O código acima retornará o erro</p>\n<blockquote>\n<p><em>A class can only implement an object type or intersection of object types with statically known members.</em></p>\n</blockquote>\n<p>Ou, em tradução livre:</p>\n<blockquote>\n<p>Uma classe somente pode implementar um objeto ou interseção de objetos com uma quantidade de membros bem definida.</p>\n</blockquote>\n<h1>Resumindo</h1>\n<p>Como eu disse, as diferenças são bem sutis e específicas, apesar delas existirem. Na prática, realmente, na maioria dos casos não vai fazer diferença nenhuma se eu descrever um objeto com type alias ou interface, ou declarar um tipo primitivo com type alias ou informar na própria declaração da variável. Porém, na minha opinião (e, agora, entendendo melhor essas diferenças), acredito que seria bem legal levar o peso semântico em consideração:</p>\n<ul>\n<li>Se eu estou trabalhando com orientação a objeto, descrever um objeto com interface tem muito mais significado do que declarar um type alias;</li>\n<li>Se eu vou declarar apenas um tipo simples, pode ser muito melhor declarar inline, junto com a variável, do que criar um type alias;</li>\n<li>Se eu vou criar um tipo um pouco mais complexo, mas que não precisa ser um objeto (como um union, por exemplo), aí pode ser melhor usar um type alias;</li>\n</ul>\n<p>Mas essa é só a minha opinião. No dia a dia, vale definir um padrão com a sua equipe, ou seguir o padrão que ela já determinou.</p>\n<p>E aí, já sabia dessas diferenças? E qual a sua opinião sobre o melhor uso em cada cenário? Escreve aí nos comentários.</p>\n<p>Fonte: <a href=\"https://stackoverflow.com/a/52682220/10545860\">TypeScript: Interfaces vs Types</a></p>"}},"pageContext":{"slug":"/typescript-interface-x-type-alias/","nextPost":{"frontmatter":{"title":"Deixe a minificação para o computador"},"fields":{"slug":"/deixe-a-minificacao-para-o-computador/"}},"previousPost":{"frontmatter":{"title":"Boletim de Sexta - 18/12/2020"},"fields":{"slug":"/boletim-de-sexta-18-12-2020/"}}}},"staticQueryHashes":["2563868181","3014040303","3054600814","764694655","96473684"]}