100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Dart Variables and Types

How Dart's var, final, and const declarations work, an overview of Dart's built-in types, and how type inference lets Dart stay statically typed while looking concise.

FoundationsBeginner8 min readJul 10, 2026
Analogies

Dart Variables and Types

Every variable in Dart has a type, whether you write it explicitly (int age = 25;) or let the compiler infer it (var age = 25;). Dart is statically typed, so once age is inferred as int, assigning a String to it later is a compile-time error, not a runtime surprise. This differs sharply from dynamically typed languages like plain JavaScript or Python, where a variable's type can silently change at runtime. Dart's type system exists to catch mistakes early, enable IDE autocompletion, and let the compiler generate faster machine code because it knows exactly what shape of data it's working with at every point in the program.

🏏

Cricket analogy: A Dart variable locking into a type once inferred is like a player registered as a specialist batter for a franchise; the team sheet doesn't let them suddenly bowl a full over just because the situation changes mid-match.

var, final, and const

var declares a variable whose value can be reassigned later, with its type inferred once from the first assignment. final declares a variable that can be set only once — you can compute its value at runtime (like final now = DateTime.now();), but you can never reassign it afterward. const is stricter still: it must be a compile-time constant, meaning its value has to be known before the program even runs, so const pi = 3.14159; is valid but const now = DateTime.now(); is not, because DateTime.now() depends on runtime state. In practice, Dart style guides recommend preferring final for anything that doesn't need reassignment, and const whenever the value truly is fixed at compile time, since const objects are canonicalized and reused in memory rather than recreated.

🏏

Cricket analogy: A final variable is like a toss result: once the umpire calls it, that outcome can never be changed for the rest of the match, even though it wasn't known before the coin was actually flipped.

Dart's Built-in Types

Dart's core numeric types are int for whole numbers and double for 64-bit floating-point values; both are subtypes of the abstract num type. String represents text and supports both single and double quotes plus multi-line strings with triple quotes, and string interpolation via $variable or ${expression} inside the string. bool holds true or false only — Dart never treats 0, an empty string, or null as falsy the way JavaScript or Python does. Collection types round out the essentials: List<T> is an ordered, indexable sequence, Set<T> is an unordered collection with no duplicates, and Map<K, V> stores key-value pairs, and all three support generics so a List<int> is statically guaranteed to never accidentally contain a String.

🏏

Cricket analogy: Dart's bool only ever being strictly true or false, never a fuzzy 0 or empty string, is like the third umpire's decision on a run-out: it's either out or not out, there's no ambiguous 'sort of out' verdict allowed.

Type Inference and dynamic

When you write var name = 'Alice';, Dart's type inference engine looks at the right-hand side and permanently fixes name's static type as String — this is not the same as JavaScript's var, which allows the type to drift with each reassignment. Dart also has a special escape hatch, dynamic, which tells the compiler to skip static type checking for that variable entirely and defer all type checks to runtime; this is occasionally necessary when working with loosely typed JSON data, but it forfeits the compiler's safety net and IDE autocompletion, so idiomatic Dart code uses dynamic sparingly and prefers explicit types or var with inference wherever possible.

🏏

Cricket analogy: Dart's var permanently fixing a type on first assignment, unlike JavaScript's freely drifting var, is like a player who debuts as a specialist opener and stays classified that way for the whole tournament, rather than being re-registered as a bowler mid-series.

dart
void main() {
  var name = 'Alice';           // inferred as String
  final age = 30;               // set once, computed or literal
  const pi = 3.14159;           // compile-time constant

  int score = 95;
  double average = 87.5;
  bool isPassing = average >= 60;

  List<String> fruits = ['apple', 'banana', 'cherry'];
  Set<int> uniqueIds = {101, 102, 103};
  Map<String, int> ages = {'Alice': 30, 'Bob': 25};

  print('$name is $age years old. Passing: $isPassing');
  print('Fruits: $fruits, Bob\'s age: ${ages['Bob']}');
}

Dart's num type is the common supertype of both int and double, so a function parameter typed num can accept either — useful for math utilities that shouldn't care whether the caller passes a whole number or a decimal.

  • Dart is statically typed: every variable has a fixed type, either written explicitly or inferred once from its initial value.
  • var allows reassignment, final can be set only once (even from a runtime value), and const must be a compile-time constant.
  • Core types include int, double (both under num), String, and bool, plus generic collections List<T>, Set<T>, and Map<K, V>.
  • Dart's bool is strictly true/false — there is no implicit truthy/falsy coercion like in JavaScript or Python.
  • dynamic opts a variable out of static type checking entirely and should be used sparingly, mainly for loosely typed data like raw JSON.
  • Preferring final over var when reassignment isn't needed is standard Dart style, and improves both readability and safety.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#DartStudyNotes#DartVariablesAndTypes#Dart#Variables#Types#Var#StudyNotes#SkillVeris#ExamPrep