← Flutter & Dart

Dart Fundamentals

What are Dart's basic data types, and what's the difference between `dynamic`, `Object`, and `var`?

Show answer — try answering out loud first

The basic types are int, double, num, String, bool, List, Set, Map, and the Runes symbols. int and double are subtypes of num. The key difference: var infers a fixed type at compile time, Object accepts any value but only exposes Object's methods, and dynamic turns off type checking (dangerous).

Dart is a strongly typed language with inference. Its numeric types:

  • int: integers (no decimals).
  • double: numbers with decimals.
  • num: the "parent" of int and double. Useful when a value could be either one.

Other common types: String (text), bool (true/false), List (arrays), Set (unique elements), and Map (key-value).

The three ways to "not commit to a type":

  • var: NOT a type. It's inference: Dart figures out the type at compile time and locks it in from then on. var x = 5; makes x an int forever.
  • Object (or Object?): accepts any value, but you can only use methods that exist on Object (like toString()). The compiler forces you to check the type before using it as something more specific.
  • dynamic: turns off type checking. You can call any method, and the error, if there is one, blows up at runtime. Use it as little as possible.
void main() {
  int whole = 42;
  double decimal = 3.14;
  num anything = 10; // could be int or double
  String text = "Flutter";
  bool active = true;

  // var: the type is locked in after inference
  var age = 25; // age is int
  // age = "twenty"; // Error: you can't assign a String to an int

  // Object: accepts everything, but limits the methods
  Object something = "hi";
  print(something.toString()); // OK
  // print(something.length); // Error: Object has no .length

  // dynamic: no checking (dangerous)
  dynamic free = "hi";
  print(free.length); // 4, works at runtime
  free = 10;
  // print(free.length); // Blows up at runtime: int has no .length
}

Using dynamic "for convenience" to avoid thinking about types. That throws away one of Dart's biggest advantages: the compiler catching errors before you run. If you truly don't know the type, Object? with a check (is) is almost always safer than dynamic.

"Dart has types like int, double (both children of num), String, bool, List, Set, and Map. For cases where I don't lock in the type, var lets Dart infer it and then keeps it fixed; Object accepts any value but forces me to check the type before using it; and dynamic disables checking, which I only use in very specific cases because errors move to runtime."

Quick challenge

What's the difference between these two declarations?

var a = 5;
dynamic b = 5;
See answer

a is locked in as int: if you try a = "hi" you get a compile-time error. b is dynamic: you can reassign a String to it with no problem (b = "hi"), because there's no type checking. var is safe; dynamic moves errors to runtime.