TypeScript - Novidades que você não conhecia
Tags: ptbr, javascript, typescript, webdev
Published: 2019-06-11 03:05:22

## Uma visão dos recursos do TypeScript 3

O TypeScript é uma linguagem compilada orientada a objeto, de código aberto e fortemente tipada desenvolvida e mantida pela Microsoft, é um superconjunto do JavaScript muito popular, que foi construído para trazer tipos estáticos para o JavaScript moderno. O compilador TypeScript lê um código TypeScript, que tem coisas como declarações de tipo e anotações de tipo, e emite um JavaScript limpo e legível com essas construções transformadas e removidas. Esse código é executado em qualquer ambiente de execução ECMAScript como seus navegadores favoritos e Node.js.

> Em essência, essa experiência significa analisar seu código para capturar coisas como bugs e erros de digitação antes que os usuários encontrem eles; mas a linguagem traz mais que isso -  [Daniel Rosenwasser](https://devblogs.microsoft.com/typescript/author/danielrosenwasser/)

Neste post, você será apresentado a alguns recursos incríveis que foram fornecidos com o TypeScript nas várias versões 3.x. O TypeScript está atualmente [na versão 3.4](https://www.typescriptlang.org/#download-links) e a próxima versão está configurada para ser lançada [no final deste mês](https://github.com/Microsoft/TypeScript/wiki/Roadmap).

Versões de TypeScript:

- [3.0 lançado em julho de 2018](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html)
- [3.1 lançado em setembro de 2018](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-1.html)
- [3.2 lançado em novembro de 2018](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-2.html)
- [3.3 lançado em janeiro de 2019](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-3.html)
- [3.4 lançado em março de 2019](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html)

Esses novos recursos serão explicados em ordem cronológica:

Uma dica gratuita: use [Bit (GitHub)](https://github.com/teambit/bit) para gerenciar, compartilhar e reutilizar facilmente seus componentes JS / TS. Modularidade e reutilização são fatores-chave para um código melhor e mais sustentável!

![](https://cdn-images-1.medium.com/max/1600/1*ODhvAjHjB8zPErBYhOFePQ.gif)
_Use Bit para compartilhar seus componentes (um exemplo)_

# Referências do Projeto

[Este novo conceito](https://www.typescriptlang.org/docs/handbook/project-references.html) foi lançado com o TypeScript 3.0, basicamente permite que um projeto TypeScript dependa de outro projeto TypeScript referenciando os arquivos `tsconfig.json`. Isso incentiva uma maneira mais modular de escrever código. O TypeScript 3.0 também introduz um novo modo para o `tsc`, a flag `--buildflag`, que funciona perfeitamente com as referências do projeto para causar construções mais rápidas.

# Novo tipo `unknown`

Um novo tipo superior também foi [introduzido no TypeScript 3.0](https://devblogs.microsoft.com/typescript/announcing-typescript-3-0/#the-unknown-type), o tipo `unknown`. É como o tipo `any`, mas é um tipo seguro para uso. Em uso, qualquer coisa pode ser atribuída ao tipo `unknown`, mas o tipo `unknown` não é atribuível a nada além de si mesmo e `any` sem uma confirmação de tipo ou um estreitamento de tipo baseado em fluxo de controle.

# defaultProps suporte em JSX

Para o desenvolvimento principalmente em React com JSX, o TypeScript 3.0 é fornecido com suporte para um novo alias de tipos no namespace `JSX` chamado `LibraryManagedAttributes`. É um tipo auxiliar que define alterações nos tipos das props de um componentes antes do seu uso. Isso agora permite modificações em torno das props e mapeamentos fornecidos e inferidos.

```ts
export interface Props {
    name: string;
}

export class Greet extends React.Component<Props> {
    render() {
        const { name } = this.props;
        return <div>Hello {name.toUpperCase()}!</div>;
    }
    static defaultProps = { name: "world"};
}

// O tipo é verificado! Nenhuma asserção de tipo é necessária!
let el = <Greet />
```

É importante observar, no entanto, que as propriedades padrão são inferidas a partir do do tipo das propriedades do `defaultProps`, portanto, se uma anotação de tipo explícito for adicionada, o compilador não poderá identificar as propriedades padrão.

# Tipos Mapeados em Tuplas e Arrays

No TypeScript 3.1, ao invés de introduzir um novo conceito para mapeamento em tupla, os tipos de objeto mapeados agora funcionam como deveriam ao iterar sobre tuplas e arrays. Isso significa que, se você já estiver usando tipos mapeados, como `Partial` ou `Required` da `lib.d.ts`, eles funcionaram automaticamente em tuplas e arrays. Isso deixa o TypeScript melhor equipado para expressar funções semelhantes a `Promise.all`.

```ts
type MapToPromise<T> = { [K in keyof T]: Promise<T[K]> };

type Coordinate = [number, number]

type PromiseCoordinate = MapToPromise<Coordinate>; // [Promise<number>, Promise<number>]
```

`MapToPromise` pega um tipo `T` e, quando esse tipo é semelhante a uma tupla, como `Coordinate`, somente as propriedades numéricas são convertidas. Em `[number, number]`, existem duas propriedades nomeadas numericamente: `0` e `1`. Quando recebem uma tupla como essa, `MapToPromise` cria uma nova tupla onde as propriedades `0` e `1` são `Promises` do tipo original. Então o tipo resultante `PromiseCoordinate` acaba com o tipo `[Promise<number>, Promise<number>]`.

# Seleção de Versão

Este é um recurso muito interessante fornecido com a versão do TypeScript 3.1, uma forma de o desenvolvedor e o compilador usarem novos recursos e acompanharem versões em uso ao mesmo tempo. Ao usar a resolução de módulo `node` no TypeScript 3.1, quando o TypeScript abre um arquivo `package.json` para descobrir quais arquivos ele precisa ler, ele primeiro analisa um novo campo chamado `typesVersions`. Um `package.json` com um campo `typesVersions` pode ser assim:

```json
{
  "name": "package-name",
  "version": "1.0",
  "types": "./index.d.ts",
  "typesVersions": {
    ">=3.1": { "*": ["ts3.1/*"] }
  }
}
```

O `package.json` informa ao TypeScript para verificar se a versão atual do TypeScript está sendo executada. Se for 3.1 ou posterior, ele usa o caminho que você declarou em relação ao pacote e lê a partir da pasta `ts3.1`.

# strictBindCallApply

JavaScript tem os métodos `bind`, `call` e `apply` que podem ser utilizados nas funções que nos permitem fazer coisas como conectar o `this` e aplicar parcialmente argumentos, chamadas de funções com um valor diferente para `this` e chamar funções com um array para os seus argumentos. A equipe do TypeScript demorou um pouco para modelar essas funções e inicialmente, todas elas recebiam qualquer número de argumentos e retornavam `any`.

Na versão 3.1, eles pegaram os tipos de parâmetro e combinaram com o conceito de modelagem de listas de parâmetros com tipos de tupla, para garantir o uso de `bind`, `call` e `apply` que são mais estritamente controlados quando usamos uma nova flag chamada `strictBindCallApply`. Ao utilizar esta nova flag, os métodos em objetos que podem ser chamadas são descritos por um novo tipo global chamado `CallableFunction` que declara versões mais estritas das assinaturas para `bind`, `call`, e `apply`.

Por exemplo:

```ts
function foo(a: number, b: string): string {
    return a + b;
}

// erro: poucos argumentos
let a = foo.apply(undefined, [10]);              

// erro: segundo argumento é um número
let b = foo.apply(undefined, [10, 20]);          

// erro: muitos argumentos
let c = foo.apply(undefined, [10, "hello", 30]);

// okay! retorna uma string
let d = foo.apply(undefined, [10, "hello"]);
```

Assim, quer você faça alguma meta-programação sofisticada ou use padrões simples como métodos de vinculação em suas instâncias de classe, esse recurso pode ajudar a capturar muitos bugs.

# Suporte ao BigInt

`BigInt` é um objeto interno que fornece uma maneira de representar números inteiros maiores que 2 elevado á 53, que é o maior número que o JavaScript pode representar com segurança com o primitivo `Number`. O TypeScript 3.2 traz verificação de tipo para BigInts, bem como suporte para a emissão de literais BigInt ao utilizar `esnext`.

A sintaxe no TypeScript para o novo tipo primitivo é chamado de `bigint`. Você pode obter um `bigint` chamando a função `BigInt()` ou escrevendo um literal BigInt adicionando um `n` no final de qualquer literal numérico inteiro:

```ts
// função BigInt
let foo: bigint = BigInt(100);

// um literal BigInt
let bar: bigint = 100n;

// *Dá um tapa no capô da função fibonacci*
// Esse bad boy retorna ints que podem ficar *tão* grande!
function fibonacci(n: bigint) {
    let result = 1n;
    for (let last = 0n, i = 0n; i < n; i++) {
        const current = result;
        result += last;
        last = current;
    }
    return result;
}
fibonacci(10000n)
```

# Herança no tsconfig.json com pacotes Node.js

No TypeScript 3.2, `tsconfig.json` pode ser resolvido da pasta `node_modules`. Ao usar um caminho simples para o campo `"extends"` no `tsconfig.json`, o TypeScript mergulhará nos pacotes do `node_modules`.

```json
{
    "extends": "@my-team/tsconfig-base",
    "include": ["./**/*"]
    "compilerOptions": {
        // Você pode mudar opções por projeto.
        "strictBindCallApply": false,
    }
}
```


Aqui, o TypeScript irá olhar em `node_modules` e procurar por um pacote `@my-team/tsconfig-base`. Em cada um desses pacotes, o TypeScript verifica primeiro se `package.json` contém um campo `"tsconfig"` e, em seguida, tenta carregar um arquivo de configuração desse campo. Se não existir, o TypeScript tentará ler de um `tsconfig.json` na raiz desse pacote. Isso é semelhante ao processo de pesquisa de arquivos `.js` em pacotes que o Node usa e o processo de pesquisa de arquivos `.d.ts` que o TypeScript já usa. Imagine como isso é útil para projetos muito grandes!

# Asserções const

O TypeScript 3.4 traz uma nova construção para valores literais chamado asserções `const`. A sintaxe é uma afirmação de tipo `const` no lugar do nome do tipo (por exemplo `123 as const`). Quando construímos novas expressões literais com asserções `const`, podemos sinalizar para a linguagem que os arrays são somente tuplas, ou que os objetos literais tem propriedades de somente leitura.

```ts
// Tipo '"hello"'
let x = "hello" as const;

// Tipo 'readonly [10, 20]'
let y = [10, 20] as const;

// Tipo '{ readonly text: "hello" }'
let z = { text: "hello" } as const;
```

# Verificação de tipo para globalThis

A equipe do TypeScript também trabalhou na árdua tarefa de tentar acessar valores no escopo global, o novo TypeScript 3.4 introduz o suporte para verificação de tipo no novo objeto do ECMAScript `globalThis` - esta é uma variável global que aponta para o escopo global. Ao contrário de outras soluções, `globalThis` fornece uma maneira padrão para acessar o escopo global que pode ser usado em diferentes ambientes.

```ts
// em um arquivo global:
var abc = 100;

// Se refere ao 'abc' acima.
globalThis.abc = 200;
```

Perceba que variáveis ​​globais declaradas com `let` e `const` não aparecem em `globalThis`.

# Conclusão

Você foi apresentado à maioria dos novos recursos do Typescript desde a versão 3.0, a próxima versão do TypeScript será lançada em algumas semanas, de acordo com o [roteiro oficial](https://github.com/Microsoft/TypeScript/wiki/Roadmap). Todas as alterações podem ser [vistas aqui](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes). Qual é o seu recurso favorito?

https://blog.bitsrc.io/11-angular-component-libraries-you-should-know-in-2018-e9f9c9d544ff

https://blog.bitsrc.io/6-javascript-user-authentication-libraries-for-2019-6c7c45fbe458

https://blog.bitsrc.io/how-to-easily-share-react-components-between-projects-3dd42149c09

# Créditos ⭐️
- [New Features in TypeScript You Didn’t Know Exist](https://medium.com/better-programming/typescript-generics-90be93d8c292), escrito originalmente por [@viclotana](https://blog.bitsrc.io/@viclotana)