Ultimamente estamos falando bastante das novas propostas do JavaScript no TC39 e novas features que estão saindo e sendo desenvolvidas a cada dia. Hoje vamos falar sobre uma das features mais esperadas para a linguagem que está presente em todo o lugar.
O que é o Optional Chaining?
Com certeza você já passou por uma situação destas: Imagine que você tem um objeto que possui uma série de parâmetros aninhados que podem ou não existir, por exemplo:
const artist = {
name: 'Lucas',
age: 24,
categories: ['rock', 'pop'],
band: 'Red Hot Chilli Peppers',
pets: [
{ name: 'Newton', type: 'cat' },
{ name: 'Panqueca', type: 'dog' }
]
}
Imagine que as propriedades pets e band podem ser nulos e vamos mais além, o caminho pets[0].name pode não existir, sendo um array do objetos do tipo { type: string } ou { name: string, type: string }.
Se fossemos fazer um tratamento para tudo isso teríamos que fazer algo deste tipo:
let bandName = null
if (artist && artist.band) {
bandName = artist.band
}
let pets = []
if (artist && artist.pets) {
pets = artist.pets.map(pet => {
if (pet && pet.name) return pet.name
return pet.type
})
}
console.log(bandName, pets)
Claro que poderíamos reduzir para ternários desta forma:
let bandName = artist && artist.band ? artist.band : null
let pets = artist && artist.pets ? artist.pets.map(pet => pet && pet.name ? pet.name : pet.type) : []
Mas veja que estamos fazendo várias verificações para podermos, de fato, buscar o valor que queremos, não seria muito mais fácil se pudéssemos fazer isso de uma única vez?
A proposta do Optional Chaining é justamente transformar todos esses tratamentos em um novo operador ?., a ideia é que, quando uma chave de um objeto não for encontrado, o JS use o padrão de short circuit para poder retornar um undefined logo de cara, por exemplo, vamos traduzir o nosso exemplo com ternários para um exemplo com o Optional Chaining:
let bandName = artist?.band
let pets = artist?.pets?.map(pet => pet?.name || pet.type)
Viu como ficou tudo muito mais conciso e muito mais fácil de entender? Por padrão o Optional Chaining vai retornar undefined se um dos campos precedido por ?. não for encontrado, então vamos examinar nossos casos de retorno:
- Se ambos band e pet.name existirem, nosso retorno será Red Hot Chilli Peppers [Newton, Panqueca]
- Se band não existir nosso retorno será undefined [Newton, Panqueca]
- Se band existir e apenas um dos pets não tiver a propriedade name nosso retorno será Red Hot Chilli Peppers [cat, Panqueca]
- Se nem band e nenhum dos pets possuir name vamos ter undefined [cat, dog]
- Se nenhum deles existir vamos ter undefined undefined
Optional Chaining com Nullish Coalescing operator
Outra proposta que ficou bastante famosa é o Nullish Coalescing operator, o que ela faz é basicamente testar valores para null e undefined. Ao invés do nosso ternário ? que faz o teste para tudo que for falsy, ou seja, tudo que se resolve para false, vamos ter um operador ?? que só resolve true se o dado operado for null ou undefined.
let bandName = artist?.band ?? 'Sem Banda'
let pets = artist?.pets?.map(pet => pet?.name || pet?.type) ?? 'Sem pets'
Agora, para o nosso caso 5 vamos ter Sem banda Sem pets como saída.
Optional Chaining e Nullish Coalescing com TypeScript
O TypeScript 3.7 já vem, por padrão, suportando estas novas propostas. Para podermos utilizar em nosso código, podemos simplesmente instalar o compilador do TS globalmente com npm i -g typescript@3.7. Porém, se você está usando o VSCode, deve imaginar que ele já vem com uma versão pré instalada do TypeScript, e ela não é a versão 3.7.
Temos duas opções nesse caso, podemos ou instalar em nosso projeto local com npm i typescript@3.7 -D e então clicarmos no canto inferior direito sobre a versão do TypeScript quando tivermos um projeto TS aberto no nosso editor e selecionar uma nova versão. Ou então podemos forçar com que o VSCode sempre utilize a versão mais nova do TypeScript.
Podemos realizar a segunda opção através da instalação de uma extensão chamada JavaScript and TypeScript Nightly, o que ela vai fazer é forçar com que seu VSCode sempre utilize a build da versão mais recente do repositório do TypeScript. Esta é uma extensão oficial feita pela Microsoft e é segura de ser utilizada em seus projetos.
Se você estiver utilizando babel, você pode instalar o plugin para optional chaining e registrá-lo na sua configuração
Conclusão
O Optional Chaining e o Nullish Coalescing operator não estão presentes em todos os browsers, enquanto o Nullish Coalescing não está ainda implementado em nenhum dos browsers maiores, o Optional Chaining já está funcionando na maioria dos browsers que rodam o V8 como engine, como o Chrome e o Opera.
Até mais!