var lets the compiler pick the type from the initializer. Each binding still has a fixed static type, so int mixed with double widens the result to double while a quoted literal stays a String.

Program

Play the program to watch Dart infer int, double, String, and a widened total.

types_inference.dart
Replay: real traced execution (multi-file project)
void main() {
  var count = 3;
  var price = 2.5;
  var label = 'items';
  var total = count * price;
  print('$count $label cost $total');
}
  1. count ← 3 (int)

    1void main() {2  var count = 3;3  var price = 2.5;
    values this step3 (int)count
  2. price ← 2.5 (double)

    2var count = 3;3var price = 2.5;4var label = 'items';
    values this step2.5 (double)price
  3. label ← items (String)

    3var price = 2.5;4var label = 'items';5var total = count * price;
    values this stepitems (String)label
  4. total ← 7.5 (double)

    4var label = 'items';5var total = count * price;6print('$count $label cost $total');
    values this step7.5 (double)total3count2.5price
  5. print('$count $label cost $total');

    5  var total = count * price;6  print('$count $label cost $total');7}
    output3 items cost 7.5
    values this step3countitemslabel7.5total

Follow the Types

  1. count is 3, an int.
  2. price is 2.5, a double.
  3. label is items, a String.
  4. total is 7.5, a double.
  5. The program prints 3 items cost 7.5. | name | value | type | | --- | --- | --- | | count | 3 | int | | price | 2.5 | double | | label | items | String | | total | 7.5 | double |
var `var` lets the compiler infer the type from the initializer; the binding still has a fixed static type.
inferred numeric `3` infers `int`, `2.5` infers `double`; mixing them widens the result to `double`.
string inference A quoted literal like `'items'` infers `String`; `var` does not mean `dynamic`.

Exercise: types_inference.dart

Reproduce 3 items cost 7.5, then identify the value and type of each visible binding.