Proteções de tipo TypeScript
Type guards são um recurso poderoso no TypeScript que permite que os desenvolvedores realizem verificações de tempo de execução para restringir o tipo de uma variável. Isso garante informações de tipo mais precisas, levando a um código mais seguro e previsível. Este artigo explora o que são type guards e como usá-los efetivamente.
O que são proteções de tipo?
Os guardas de tipo são expressões que realizam verificações de tempo de execução e permitem que o TypeScript infira um tipo mais específico para uma variável. Eles ajudam a discriminar entre diferentes tipos, especialmente ao lidar com tipos de união. Os guardas de tipo podem ser implementados usando várias técnicas, incluindo:
- Predicados de tipo definidos pelo usuário
- Afirmações de tipo
- Verificações de instância
- Usando o operador
typeof
- Usando o operador
in
Predicados de tipo definidos pelo usuário
Predicados de tipo definidos pelo usuário são funções que retornam um valor booleano e têm um tipo de retorno especial que indica o tipo da variável que está sendo verificada. Veja como criá-los e usá-los:
function isString(value: any): value is string {
return typeof value === 'string';
}
function printString(value: any) {
if (isString(value)) {
console.log(value.toUpperCase()); // TypeScript knows value is a string here
} else {
console.log('Not a string');
}
}
No exemplo acima, isString
é um predicado de tipo definido pelo usuário que ajuda o TypeScript a entender que value
é uma string dentro do bloco if
.
Afirmações de tipo
Asserções de tipo dizem ao TypeScript para tratar uma variável como um determinado tipo. Este método não realiza uma verificação de tempo de execução, mas informa o compilador TypeScript sobre o tipo. Por exemplo:
function printLength(value: any) {
console.log((value as string).length); // Assert value is a string
}
Neste exemplo, value as string
informa ao TypeScript para assumir que value
é uma string sem realizar uma verificação em tempo de execução.
Verificações de instância
Verificações de instância são usadas para determinar se um objeto é uma instância de uma classe específica. Isso é útil para restringir tipos ao trabalhar com classes:
class Dog {
bark() { console.log('Woof'); }
}
class Cat {
meow() { console.log('Meow'); }
}
function speak(animal: Dog | Cat) {
if (animal instanceof Dog) {
animal.bark(); // TypeScript knows animal is a Dog here
} else {
animal.meow(); // TypeScript knows animal is a Cat here
}
}
Neste exemplo, o operador instanceof
ajuda o TypeScript a inferir o tipo de animal
com base em sua classe.
Usando o operador typeof
O operador typeof
pode ser usado para verificar tipos primitivos como string
, number
e boolean
:
function processValue(value: string | number) {
if (typeof value === 'string') {
console.log(value.toUpperCase()); // TypeScript knows value is a string here
} else {
console.log(value.toFixed(2)); // TypeScript knows value is a number here
}
}
Aqui, typeof
é usado para verificar se value
é uma string
ou um number
e restringe o tipo adequadamente.
Usando o operador in
O operador in
verifica a presença de uma propriedade em um objeto. Isso é útil para distinguir entre tipos que compartilham propriedades comuns:
interface Bird {
fly: () => void;
}
interface Fish {
swim: () => void;
}
function move(creature: Bird | Fish) {
if ('fly' in creature) {
creature.fly(); // TypeScript knows creature is a Bird here
} else {
creature.swim(); // TypeScript knows creature is a Fish here
}
}
Neste exemplo, o operador in
ajuda o TypeScript a determinar se creature
é um Bird
ou um Fish
com base na presença de um método.
Conclusão
Os type guards do TypeScript são ferramentas essenciais para trabalhar com tipos de forma flexível e segura. Eles permitem uma verificação de tipo mais precisa e podem evitar erros de tempo de execução, garantindo que o tipo correto seja usado em diferentes cenários. Entender e usar os type guards de forma eficaz pode levar a um código TypeScript mais robusto e sustentável.