DEV Community

Cover image for Typescript e sua palavra-chave "type"
Antônio Carlos Durães da Silva
Antônio Carlos Durães da Silva

Posted on

Typescript e sua palavra-chave "type"

Não é novidade que o Typescript é um superset que veio para trazer conceitos de Orientação a Objeto para a linguagem Javascript. Contudo, algumas palavras-chave dessa linguagem criada pela Microsoft ainda geram dúvidas.

Além da modelagem de entidades e objetos de valor por meio de classes, também é possível realizar tal modelagem utilizando uma interface ou um type. Abaixo estão um exemplo de modelagem usando cada recurso da linguagem.

class People {
    name: string;
    age: number;
}

interface People {
    name: string;
    age: number;
}

type People = {
    name: string;
    age: number;
}
Enter fullscreen mode Exit fullscreen mode

Neste momento você deve estar pensando: "Se é possível realizar a modelagem de qualquer uma das três maneiras, por que eu deveria utilizar ou entender sobre o type?". A resposta é simples, há usos que só o uso do recurso type possibilita, abaixo discorro mais sobre cada um desses cenários.

Type aliases

Como nome indica, é possível apelidar, isto é, dar um alias a um tipo já existente, seja ele declarado como classe, interface, outro type ou de tipo primitivo.

type Student = People;

type Guid = string;
Enter fullscreen mode Exit fullscreen mode

No exemplo acima, criamos um tipo chamado "Estudante" que, basicamente, é um apelido para o modelo "Pessoa". Também criamos um tipo para um identificador único, mapeado sobre o tipo string, já que não temos um tipo Guid (como o C# possui) em Typescript.

Apelidar um tipo existente, sobretudo tipos primitivos, é útil para trazer semântica de acordo com o contexto com que aquele tipo será usado. Um identificador do tipo string é amplo, não traz pistas sobre o formato do ID, diferentemente de um tipo GUID, que já traz no nome seu formato.

Template literals

Esse é o recurso ideal para apelidar um ou mais valores estáticos que sejam enumeráveis. Não entendeu? Bora para um exemplo.

type MonthNumber = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
Enter fullscreen mode Exit fullscreen mode

Acima estão listados os índices para cada mês do ano. A vantagem de usar tipos literais é ser avisado quando um valor incorreto, isto é, que não pertence ao conjunto definido, for utilizado, como mostra o exemplo abaixo:
Exemplo de erro ao tentar atribuir o valor 13 como número válido para um índice de um mês do ano

Union types

Em resumo, é possível declarar um tipo que aceite múltiplos outros tipos (primitivos, classe, interface, type, literal), ou seja, um tipo que una outros tipos.

Abaixo criamos um tipo ID que aceita tanto valores do tipo string (caso seja um GUID, por exemplo) quanto do tipo number (caso seja um inteiro auto-incremental, por exemplo).

type ID = string | number;

const peopleId: ID = 13;

const postId: ID = '08288a85-b79b-4022-a0dd-1563bd0f5de1';
Enter fullscreen mode Exit fullscreen mode

Intersection types

Além de permitir aceitar múltiplos tipos como válido para um novo, também é possível unir vários tipos, isso mesmo, criar um tipo que seja a fusão de propriedades de outros dois ou mais. Este cenário de uso é restrito a declaração de entidades, não se aplica a valores primitivos.

No exemplo abaixo criamos uma entidade (Pessoa) e um objeto de valor (Endereço). Com o operador "&" conseguimos unificar os dois tipos em um novo, uma entidade para representar uma pessoa com endereço. Esse terceiro tipo conterá todos os atributos dos dois que lhe originaram.

class People {
    name: string;
    age: number;
    id: ID;
}

interface Address {
    country: string;
    city: string;
}

type PeopleWithAddress = People & Address;

const george: PeopleWithAddress = {
    age: 19,
    city: 'Serra',
    country: 'BR',
    id: 25,
    name: 'George',
    zipCode: 251475899
};
Enter fullscreen mode Exit fullscreen mode

Considerações finais

Com esses recursos não há mais desculpas para deixar constantes espalhadas como strings ou numbers espalhados pelo código, ou para repetir todas propriedades de um modelo em outro. É possível ter validação de valores em tempo de desenvolvimento e economizar linhas de declaração de modelo :)

References:
Types aliases
Literal types
Union types
Intersection types

Oldest comments (0)