TypeScript - Tipagem Estática e Generics
Tags: typescript, beginners, programming, braziliandevs
Published: 2022-05-10 20:52:28

## Tabela de Conteúdos

- [Enum](#enum)
- [Tipos de Coleção](#tipos-de-coleção)
- [Type Aliases](#type-aliases)
- [Type Unions](#type-unions)
- [Classes](#classes)
- [Interfaces](#interface)
- [Generics](#generics)
- [Links Úteis](#links-úteis)

---

## Enum

### O que é?

É uma estrutura de dados não natural do JavaScript, ela é um conjunto de valores relacionados, o que possibilita a criação de um conjunto de constantes para uso.

### Funcionamento

Como dito em sua definição, a estrutura Enum é um conjunto de valores, esses que podem ser comparados aos valores de um objeto JS, pois tem a estrutura de chave/valor.

A maior diferença entre Enum e objetos JS, é que a Enumeração tem uma atribuição automática de valores, similar aos índices de um Array, ou seja, a primeira chave terá o valor 0, a segunda o valor 1 e assim por diante, isso caso não houver uma atribuição explícita de outro valor.

Também é possível alterar o valor de início de uma Enum, basta atribuir ao primeiro elemento o número desejado, assim caso atribuímos o valor 10 ao primeiro elemento, o segundo terá o valor 11 e assim por diante.

### Sintaxe

#### Criação

Para criarmos uma Enum utilizamos uma sintaxe muito simples, na qual usamos a palavra reservada enum, seguida do nome desejado para a enumeração e por fim abrimos e fechamos chaves, sendo que os valores da Enum devem ser colocados dentro dessas chaves.

``` ts
enum SomeEnum {
  FirstValue, // o valor será igual a 0
  SecondValue, // o valor será igual a 1
  ThirdValue, // o valor será igual a 2
}
```

Podemos também alterar o valor inicial, adequando-o para as nossas necessidades, para isso basta atribuir o número desejado ao primeiro elemento.

``` ts
enum OtherEnum {
  FirstValue = 12,
  SecondValue, // o valor será igual a 13
  ThirdValue, // o valor será igual a 14
}
```

Também há a possibilidade de definirmos os valores um a um, basta utilizar a atribuição, lembrando que a Enum pode receber outros tipos fora o Number.

``` ts
enum AnotherEnum {
  FirstValue = 'Gabriel',
  SecondValue = 'Matheus',
  ThirdValue = 'Daniel',
}
```

#### Atribuição

Para utilizarmos a estrutura Enum criada devemos definir que a variável será do tipo da Enumeração e que ela recebe determinado valor da Enum. Lembrando que o modo de criação de variável permanece o mesmo, ou seja, podemos optar por utilizar let ou const.

``` ts
const someVariable: SomeEnum = SomeEnum.FirstValue;
let someVariable: SomeEnum = SomeEnum.FirstValue;
```

Podemos atribuir o valor da Enum a variável não apenas através da dot notation como também da bracket notation.

``` ts
const someVariable: SomeEnum = SomeEnum['FirstValue'];
```

Além disso também é possível atribuir a variável não apenas o valor, como também a chave, para isso basta utilizar a bracket notation passando o valor da chave em questão entre colchetes.

``` ts
const someVariable: SomeEnum = SomeEnum[0];
```

<br />

<small>[Voltar ao topo](#tabela-de-conteúdos)</small>

---

## Tipos de Coleção

### O que são?

São as formas que podemos agrupar dados, ou seja, criar um coleção de dados.

### Quais são?

As duas estruturas disponibilizadas pelo TS para agrupar valores são os Arrays e as Tuplas.

Os Arrays no TypeScript funcionam de forma idêntica aos do JavaScript, são estruturas de tamanhos dinâmicos que podem receber diferentes elementos, porém no TS precisamos informar previamente quais são esses elementos.

Já as Tuplas são estruturas de ordem, tamanho e tipo fixos, ou seja, o desenvolvedor deve saber a ordem, o tamanho e os tipos de valores que a estrutura aceita.

### Sintaxe

#### Arrays

Para criarmos Arrays tipados usamos uma sintaxe composta do tipo de dado que o Array irá comportar, seguido dos colchetes.

``` ts
const someArray: string[] = ['Gabriel', 'João', 'Marcus'];
const otherArray: number[] = [1, 23, 456];
```
``` ts
const someArray: Array<string> = ['Gabriel', 'João', 'Marcus'];  // funciona igual: string[]
const otherArray: Array<number> = [1, 23, 456];
```

Lembrando que se não atribuirmos explicitamente o tipo de dado que o Array pode conter ele será inferido como Any, o que não é nem um pouco recomendável.

#### Tuplas

Para criarmos Tuplas utilizamos um Array de tipos em sua definição, assim criamos um _"Array"_ com ordem, tamanho e tipos fixos.

``` ts
const someTuple: [string, number, boolean] = ['Gabriel', 21, true];
```

<br />

<small>[Voltar ao topo](#tabela-de-conteúdos)</small>

---

## Type Aliases

### O que é?

Em tradução livre significa _"apelido de tipos"_, é uma forma de declarar tipos personalizados.

### Sintaxe

#### Criação

A sintaxe consiste na palavra reservada `type`, seguida do nome que desejamos dar ao _"apelido"_ e deve receber através de atribuição o novo tipo que queremos criar.

``` ts
type SomeType = {
  someValue: string;
  otherValue: number;
};
```
``` ts
type OtherType = string | number;
```

#### Utilização

Para utilizarmos o Type criado basta atribuirmos a variável através dos dois pontos, como se fossemos definir um tipo primitivo a uma variável.

``` ts
const someVariable: SomeType = { someValue: 'alguma string', otherValue: 4 };
```
``` ts
function someFunction(param: SomeType) {};
```

<br />

<small>[Voltar ao topo](#tabela-de-conteúdos)</small>

---

## Type Unions

### O que é?

É uma forma de representar tipos de dados que podem ser variáveis, apesar do TS ter tipagem estática, ainda sim podemos definir diferentes tipos para uma mesma variável, de maneira estática claro.

### Sintaxe

A sintaxe se assemelha ao operador lógico OU, assim definimos que uma variável pode receber um tipo ou outro, o sinal nesse caso é uma barra única `|`.

``` ts
const cpf: number | string;
```

Vale ressaltar que podemos utilizar esse recurso tanto em variáveis, quanto em coleções.

<br />

<small>[Voltar ao topo](#tabela-de-conteúdos)</small>

---

## Classes

### O que são?

Assim como no JavaScript, Classes são modelos para criação de objetos, porém no TypeScript devemos sempre "tipar" nossas propriedades e métodos.

Em resumo as Classes se comportam de forma idêntica no geral, com a única diferença que no TS é necessária a tipagem das propriedades e métodos.

*Obs: _Programação Orientada a Objeto não será abordada aqui_.

### Sintaxe

A sintaxe para a criação de classes é a mesma, usamos a palavra reservada `class`, em seguida damos o nome desejado a classe e abrimos chaves para a estruturação.

Como dito anteriormente, a única diferença de classes em TS é a necessidade de tipar as propriedades e métodos, porém a sintaxe para essa tipagem é exatamente igual a qualquer outra variável, função ou parâmetro.

``` ts
class SomeClass {
  constructor(prop1: string, prop2: number) {
    this.prop1 = prop1;
    this.prop2 = prop2;
  }

  someMethod(): void {};

  otherMethod(): number {};
}
```

<br />

<small>[Voltar ao topo](#tabela-de-conteúdos)</small>

---

## Interface

### O que é?

É uma estrutura que define um objeto com determinadas propriedades e métodos obrigatórios, esses que por sua vez devem ter um tipo, em termos mais comuns, podemos dizer que é uma espécie de _"contrato de código"_.

### Sintaxe

A sintaxe da Interface é similar à sintaxe do Type Aliases, sendo as duas únicas diferenças: a palavra reservada, que nesse caso é interface; e a ausência do sinal de atribuição.

``` ts
interface SomeInterface {
  someProperty: string;
  otherProperty:number;
  someMethod(): boolean;
}
```

<br />

<small>[Voltar ao topo](#tabela-de-conteúdos)</small>

---

## Generics

### O que são?

São modelos de códigos genéricos que permitem _"tipar"_ funções, classes ou interfaces, em outro momento pós definição, trazendo um certo dinamismo a tipagem.

### Funcionamento

O diferencial aqui, é que __inicialmente não temos realmente um tipo definido, justamente por ser algo genérico__, como o nome do recurso propõe. Porém ao chamarmos nosso modelo de Generics em uma função, por exemplo, o tipo genérico passará a ser aquele que nós definimos, o que facilita a reutilização de código.

### Sintaxe

A sintaxe do Generic é extremamente enxuta, consistindo apenas de dois colchetes angulares `<>`, dentro desses colchetes devemos informar o nosso tipo genérico, de forma similar a um parâmetro de função.

``` ts
function getArray<T>:(items: T[]): T[] {
  return new Array<T>().concat(items);
}
```

Na função acima estamos retornando um novo Array a partir do parâmetro, que por sua vez também é um Array. O Generics atua aqui através do T, ele indica que o Array deve ser do tipo `T`, ou seja, tem que ser de um único tipo que será definido posteriormente.

Como dito anteriormente, a definição do Generics assemelha-se a parâmetros de uma função, o que significa que podemos utilizar o nome que desejarmos para eles, porém por convenção utiliza-se o `T` como primeira opção.

``` ts
function getArray<ArrayType>:(items: ArrayType[]): ArrayType[] {
  return new Array<ArrayType>().concat(items);
}
```

A função acima com o Generics denominado ArrayType terá exatamente a mesma funcionalidade da função com o Generics denominado `T`.

<br />

<small>[Voltar ao topo](#tabela-de-conteúdos)</small>

---

## Links Úteis

- [DevHints - TypeScript CheatSheet](https://devhints.io/typescript)
- [TypeScript Docs - Generics](https://www.typescriptlang.org/docs/handbook/2/generics.html)
- [TutorialsTeacher - TypeScript Generics](https://www.tutorialsteacher.com/typescript/typescript-generic)
- [TutorialsTeacher - TypeScript Class](https://www.tutorialsteacher.com/typescript/typescript-class)
- [DevMedia - Tipos de Dados no TypeScript](https://www.devmedia.com.br/typescript-tipos-de-dados/40741)
- [YouTube - Mini Curso TypeScript Generics](https://www.youtube.com/watch?v=Zjs7IJuhdaM&list=PLlAbYrWSYTiPanrzauGa7vMuve7_vnXG_&index=13)

<br />

<small>[Voltar ao topo](#tabela-de-conteúdos)</small>