TypeScript - Novidades que você não conhecia
Eduardo Rabelo
Posted on June 11, 2019
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:
- 3.0 lançado em julho de 2018
- 3.1 lançado em setembro de 2018
- 3.2 lançado em novembro de 2018
- 3.3 lançado em janeiro de 2019
- 3.4 lançado em março de 2019
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 ⭐️
- New Features in TypeScript You Didn’t Know Exist, escrito originalmente por @viclotana
Posted on June 11, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.