DEV Community

Cover image for TypeScript - Novidades que você não conhecia
Eduardo Rabelo
Eduardo Rabelo

Posted on

TypeScript - Novidades que você não conhecia

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

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 e a próxima versão está configurada para ser lançada no final deste mês.

Versões de TypeScript:

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

Uma dica gratuita: use Bit (GitHub) 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!


Use Bit para compartilhar seus componentes (um exemplo)

Referências do Projeto

Este novo conceito 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, 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.

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.

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:

{
  "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:

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:

// 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.

{
    "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.

// 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.

// 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. Todas as alterações podem ser vistas aqui. 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 ⭐️

Top comments (0)