Visão geral dos três operadores (as /is/is!)
| Operador | Descrição da função |
|---|---|
as | Conversão forçada de tipos; também usado para definir apelidos de bibliotecas |
is | Verificação de tipo: retorna true se o objeto pertencer ao tipo especificado |
is! | Verificação de tipo: retorna true se o objeto não pertencer ao tipo especificado |
Condição para obj is T ser verdadeiro: o objeto obj implementa ou herda o tipo T (inclui classes pai, interfaces e tipos anuláveis).
Exemplo: Qualquer objeto is Object? sempre retorna true.
Operador is
Verificação segura de tipos
Verifica o tipo do objeto em tempo de execução; se o resultado for true, dentro do bloco de código você pode usar diretamente como esse tipo sem conversão manual. Se o objeto for null ou houver incompatibilidade de tipo, retorna false sem lançar exceções.
O exemplo abaixo utiliza objetos de classe. Se você ainda não aprendeu sobre classes, pense nelas apenas como modelos para criar dados.
class Person {
String firstName = '';
}
class Employee extends Person {}
void main() {
dynamic employee = Employee();
// Verificação de tipo com is
if (employee is Person) {
// Ao entrar no bloco, employee é reconhecido automaticamente como tipo Person
employee.firstName = "Jack";
print(employee.firstName); // Exibe Jack
}
dynamic emptyObj = null;
if (emptyObj is Person) {
// Não executa, null não corresponde ao tipo Person
print("Combinação bem-sucedida");
}
}Code language: Dart (dart)
O código acima define uma classe Person e depois uma classe Employee que herda de Person.
No código usamos is para checar se um objeto é do tipo Person. Se for verdadeiro, podemos manipulá-lo diretamente como Person dentro do bloco {}. Isso acontece pois usamos o tipo dinâmico em dynamic employee = Employee();.
No segundo exemplo dynamic emptyObj = null;, como o valor é null, emptyObj is Person resulta em false e o código dentro de {} não é executado.
Operador is!
Verificação inversa de tipos
Sintaxe:
variável is! tipo
Na prática, equivale a negar o resultado do operador is.
É equivalente a !(variável is tipo), verifica se o objeto não é o tipo alvo.
Veja o exemplo:
class Person {
String name = '';
}
void main() {
dynamic obj = "texto";
if (obj is! Person) {
print("obj não é do tipo Person");
}
}Code language: Dart (dart)
Nesse exemplo o código dentro do bloco é executado e imprime “obj não é do tipo Person”, pois obj não é uma instância criada a partir do modelo Person.
Operador as
Conversão forçada de tipos
Modo de utilização:
(variável as tipoAlvo).propriedade/métodoCode language: JavaScript (javascript)
Utilize apenas se tiver 100% de certeza de que o objeto corresponde ao tipo alvo; caso contrário, uma exceção de tempo de execução será lançada. Para manter a robustez do programa, não é recomendado o uso excessivo.
class Teacher {
String name = '';
}
void main() {
dynamic jason = Teacher();
// Conversão forçada para Teacher para acessar a propriedade
(jason as Teacher).name = "Jason";
print((jason as Teacher).name); // Jason
}Code language: Dart (dart)
O exemplo acima tem saída Jason
Criamos diretamente uma instância de Teacher com dynamic jason = Teacher();, então podemos garantir 100% que é um Teacher e não haverá erros nesse uso.

Se escrevermos o código abaixo, ocorrerá um erro.
class Teacher {
String name = '';
}
class Car {
String name = '';
}
void main() {
dynamic jason = Teacher();
// Conversão forçada para Car para acessar a propriedade
(jason as Car).name = "Jason";//❌erro
print((jason as Car).name); //❌erro
}Code language: Dart (dart)
O erro acontece pois jason é originalmente um objeto Teacher, mas tentamos converter ele forçadamente para Car.
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Unhandled exception:
type 'Teacher' is not a subtype of type 'Car' in type cast
#0 main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:12:10)
#1 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#2 _RawReceivePort._handleMessage (dart:isolate-patch/isolate-patch.dart:193:12)Code language: PHP (php)
Comparação principal entre as e is
// Forma 1: conversão forçada com as
(employee as Person).firstName = 'Bob';
// Forma 2: verificar antes com is e depois usar
if (employee is Person) {
employee.firstName = 'Bob';
}Code language: JavaScript (javascript)
Comportamento quando employee é null ou não é do tipo Person:
- Versão com as: a exceção
CastErroré lançada e o programa para de funcionar; - Versão com is: não entra no bloco if, sem erros e sem execução de ações.
Mesmo que precise escrever um pouco mais de código, dê preferência ao método com is, pois garante maior estabilidade ao programa.
Segundo propósito do as
Segundo propósito do as
as não serve apenas para conversão de tipos: ao importar bibliotecas, você pode definir um apelido para a biblioteca
import 'dart:math' as math;
void main() {
// Chamar classes/métodos pelo apelido da biblioteca
print(math.pi); // Exibe 3.141592653589793
}Code language: JavaScript (javascript)
Exemplo completo final
class Animal {}
class Cat extends Animal {}
void main() {
dynamic obj = Cat();
// 1. Verificação com is
if (obj is Animal) {
print("obj é do tipo Animal");
}
// 2. Verificação inversa com is!
if (obj is! String) {
print("obj não é uma string");
}
// 3. Conversão forçada com as
Animal a = obj as Animal;
// Exemplo errado que causa crash
dynamic str = "ola";
// Animal error = str as Animal; // Lança CastError
}Code language: JavaScript (javascript)