
Type inference – bringing dynamism to the show
In the previous examples, we demonstrated two ways of declaring variables: by using the type of the variable, such as int and String, or by using the var keyword.
So, now you may be wondering how Dart knows what type of variable it is if you don't specify it in a declaration.
From the Dart documentation (https://dart.dev/guides/language/effective-dart/documentation), consider the following statement:
This means that, when you declare a variable, the Dart analyzer will infer the type based on the literal or the object constructor.
Here is an example:
import 'dart:mirrors';
main() {
var someInt = 1;
print(reflect(someInt).type.reflectedType.toString()); // prints: int
}
As you can see, in this example we have only the var keyword. We didn't specify any type, but as we used an int literal (1), the analyzer tool could infer the type successfully.
Local variables get the type inferred by the analyzer in the initialization. In the preceding example, trying to assign a string value to someInt would fail.
So, let's consider the following code:
main() {
var a; // here we didn't initialized var so its
// type is the special dynamic
a = 1; // now a is a int
a = "a"; // and now a String
print(a is int); // prints false
print(a is String); // prints true
print(a is dynamic); // prints true
print(a.runtimeType); // prints String
}
As you may have noticed, a is a String type and a dynamic type. dynamic is a special type and it can assume any type at runtime; therefore, any value can be cast to dynamic too.
Dart can infer types for fields, method returns, and generic type arguments; we'll explore each one in more detail in their respective sections in this book.