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.