Watch the video (11 min)
On this page26 sections
  1. Prerequisites
  2. Connection With Previous Lectures
  3. Learning Objectives
  4. 1. What Are Type Checking and Conversion?
  5. 2. Asking a Value Its Type: runtimeType
  6. 3. runtimeType Shows the Value, Not the Label
  7. 4. Checking a Type with is
  8. 5. The Opposite Check: is!
  9. 6. Casting with as
  10. 7. When as Is Wrong
  11. 8. Text to Whole Number: int.parse
  12. 9. double.parse and num.parse
  13. 10. When Parsing Fails
  14. 11. Safe Parsing with tryParse
  15. 12. Number to Text: toString
  16. 13. Between int and double: toInt and toDouble
  17. 14. A Real-World Example
  18. Code Examples
  19. Common Beginner Mistakes
  20. Best Practices
  21. Mini Challenge
  22. Practice Questions
  23. Practice Answers
  24. Quick Revision
  25. Key Takeaways
  26. What's Next?

Lecture 10 — Type Checking & Conversion

Category2 — Variables & Data Types
Lecture010 of 140
Estimated video length11 min
TargetDart 3.12.2
LevelBeginner

The text '25' and the number 25 look the same on screen, but Dart refuses to add them. In this lecture you learn to ask a value its type, check it, and convert it from one type to another.

Contents

Prerequisites · Connection · Objectives · Lesson · Code Examples · Common Mistakes · Best Practices · Mini Challenge · Practice Questions · Answers · Takeaways

Every error message in this lecture is real. Each one was produced by running the code shown on Dart 3.12.2, so you will recognize it when you meet it yourself.


Prerequisites

Students should already understand, from Lectures 001–009:

  • declaring variables with a type or with var
  • final, const, and late
  • the types String, int, double, num, and bool
  • string interpolation with $ and ${}, and joining strings with +
  • arithmetic with int and double, and why / always gives a double

Connection With Previous Lectures

In Lectures 008 and 009 we worked with text and numbers separately. Real programs mix them. A number typed into a form, read from a file, or received over the internet arrives as text:

dart
void main() {
  var quantityText = '3';
  // var next = quantityText + 1; // ✗ a String cannot be added to an int
  print(quantityText);
}
output
3

'3' prints like a number, but it is a String, so we cannot calculate with it. We need a way to turn text into a number, a number back into text, and to find out which type a value really has.


Learning Objectives

By the end of this lecture you will be able to:

  • Find a value's type while the program runs with runtimeType
  • Check a value's type with is and is!
  • Treat a num as a more specific type with as
  • Convert text to numbers with int.parse, double.parse, and num.parse
  • Use tryParse to convert text that may not be a valid number
  • Convert numbers to text with toString
  • Convert between int and double with toInt and toDouble
  • Recognize the errors Dart produces when a check or conversion goes wrong

1. What Are Type Checking and Conversion?

Type checking means asking "what type is this value?". Type conversion means making a new value of a different type from an existing one — the number 25 from the text '25'.

Analogy — think of a currency exchange counter. You hand over dollars and receive rupees. The amount of money is the same; only its form changes, so you can spend it where rupees are needed.

Conversion never changes the original value. It produces a new value of the new type.


2. Asking a Value Its Type: runtimeType

Every value can tell you its type through .runtimeType:

dart
void main() {
  var name = 'Ali';
  var age = 20;
  var height = 5.8;
  var isStudent = true;
  print(name.runtimeType);
  print(age.runtimeType);
  print(height.runtimeType);
  print(isStudent.runtimeType);
}
output
String
int
double
bool

This is the promise from Lecture 005 kept: Dart inferred each type from the value, and now it shows us what it chose.


3. runtimeType Shows the Value, Not the Label

A num variable can hold an int or a double. runtimeType reports the type of the value inside the variable, not the type written on the declaration:

dart
void main() {
  num price = 100;
  print(price.runtimeType);
  price = 99.5;
  print(price.runtimeType);
}
output
int
double

The variable is declared num both times. The value inside changed from an int to a double.


4. Checking a Type with is

runtimeType is good for looking. To test a type, use is. It answers with a bool:

dart
void main() {
  num score = 25;
  print(score is int);
  print(score is double);
}
output
true
false

score holds 25, an int, so it is an int and not a double. Using the answer of is to make a decision needs if, which arrives in Lecture 022.


5. The Opposite Check: is!

is! means "is not". It gives the reverse answer of is:

dart
void main() {
  num temperature = 36.6;
  print(temperature is! int);
  print(temperature is! double);
}
output
true
false

36.6 is a double, so it is not an int — true — and it is a double, so is! double is false.


6. Casting with as

Sometimes you know more than Dart does. The variable says num, but you know the value is a double. as tells Dart to treat the value as that type. This is called a cast:

dart
void main() {
  num reading = 36.6;
  double temperature = reading as double;
  print(temperature);
}
output
36.6

Without as, Dart would reject double temperature = reading;, because a num might be an int. A cast does not convert anything — the value was already a double.


7. When as Is Wrong

A cast is a promise. If the value is not what you promised, the program stops while running:

dart
void main() {
  num marks = 80;
  double average = marks as double;
  print(average);
}
output
Unhandled exception:
type 'int' is not a subtype of type 'double' in type cast

80 is an int, not a double. This is a runtime error: the program compiled, then crashed on that line. (Dart also prints a list of file locations below the message, which we leave out here.) Use as only when you are sure; to actually turn an int into a double, use toDouble() from section 13.


8. Text to Whole Number: int.parse

Parsing means reading text and building a value from it. int.parse turns text that contains a whole number into an int:

dart
void main() {
  var quantityText = '3';
  var quantity = int.parse(quantityText);
  print(quantity + 1);
  print(quantity.runtimeType);
}
output
4
int

The opening problem is solved: quantityText is a String, quantity is an int, and we can calculate with it.


9. double.parse and num.parse

For text with a decimal point, use double.parse. If you do not know which kind of number the text holds, num.parse decides for you:

dart
void main() {
  print(double.parse('99.5'));
  print(double.parse('5'));
  print(num.parse('42').runtimeType);
  print(num.parse('3.5').runtimeType);
}
output
99.5
5.0
int
double

double.parse('5') gives 5.0 — the result is always a double. num.parse gives an int for '42' and a double for '3.5'.


10. When Parsing Fails

int.parse only accepts text that really is a whole number. Anything else stops the program:

dart
void main() {
  var age = int.parse('twenty');
  print(age);
}
output
Unhandled exception:
FormatException: Invalid radix-10 number (at character 1)
twenty
^

"Radix-10" simply means "an ordinary base-10 number", and the ^ marks where reading failed. int.parse('99.5') fails the same way — a decimal point is not part of a whole number. Catching errors like this one is the topic of Lecture 084, try, catch & finally.


11. Safe Parsing with tryParse

When text might not be a number, use tryParse. Instead of crashing, it gives back null, Dart's word for "no value":

dart
void main() {
  var good = int.tryParse('42');
  var bad = int.tryParse('forty-two');
  print(good);
  print(bad);
  print(double.tryParse('7.25'));
}
output
42
null
7.25

The program keeps running. Because the result might be null, Dart will not let you do arithmetic with it directly yet. null and the types that allow it are the subject of Lectures 012 and 013.


12. Number to Text: toString

Going the other way, toString() turns any number into a String:

dart
void main() {
  var age = 20;
  var ageText = age.toString();
  print(age + age);
  print(ageText + ageText);
  print(ageText.runtimeType);
}
output
40
2020
String

Same digits, different behavior: + adds two numbers but joins two strings. You have also been using toString() all along without seeing it — interpolation such as 'Age: $age' calls it for you.


13. Between int and double: toInt and toDouble

toDouble() turns an int into a double. toInt() turns a double into an int by dropping the decimal part:

dart
void main() {
  var marks = 80;
  var price = 9.99;
  print(marks.toDouble());
  print(price.toInt());
  print(price.round());
}
output
80.0
9
10

toInt() does not round: 9.99 becomes 9. If you want the nearest whole number, use round() instead.


14. A Real-World Example

An order form sends the price and quantity as text. We parse them, check the result, calculate, and convert back:

dart
void main() {
  var priceText = '450.5';
  var quantityText = '3';

  var price = num.parse(priceText);
  var quantity = int.parse(quantityText);
  var total = price * quantity;
  var totalText = total.toString();

  print('Price is a double: ${price is double}');
  print('Quantity type: ${quantity.runtimeType}');
  print('Total: $total');
  print('Whole rupees: ${total.toInt()}');
  print('Saved as: ${totalText.runtimeType}');
}
output
Price is a double: true
Quantity type: int
Total: 1351.5
Whole rupees: 1351
Saved as: String

num.parse lets the form send either '450' or '450.5', and is confirms which one arrived.

Text came in, numbers did the work, and text went back out — every type change was made on purpose.


Code Examples

Example 1 — Four Runtime Types

dart
void main() {
  var city = 'Lahore';
  var year = 2026;
  var rating = 4.5;
  var isOpen = false;
  print(city.runtimeType);
  print(year.runtimeType);
  print(rating.runtimeType);
  print(isOpen.runtimeType);
}
output
String
int
double
bool

Example 2 — is and is!

dart
void main() {
  num amount = 250;
  print(amount is int);
  print(amount is double);
  print(amount is! double);
}
output
true
false
true

Example 3 — Casting a num

dart
void main() {
  num height = 5.9;
  double heightInFeet = height as double;
  print(heightInFeet);
  print(heightInFeet.runtimeType);
}
output
5.9
double

Example 4 — Parsing Whole and Decimal Numbers

dart
void main() {
  var ageText = '21';
  var weightText = '62.5';
  var age = int.parse(ageText);
  var weight = double.parse(weightText);
  print(age + 1);
  print(weight + 0.5);
}
output
22
63.0

Example 5 — num.parse and tryParse

dart
void main() {
  print(num.parse('15').runtimeType);
  print(num.parse('15.0').runtimeType);
  print(int.tryParse('15'));
  print(int.tryParse('fifteen'));
}
output
int
double
15
null

Example 6 — toString, toInt, toDouble

dart
void main() {
  var count = 7;
  var distance = 12.8;
  print(count.toString().runtimeType);
  print(count.toDouble());
  print(distance.toInt());
}
output
String
7.0
12

How it works

  1. count.toString() makes the text '7', so its type is String.
  2. count.toDouble() makes the double 7.0.
  3. distance.toInt() drops .8 and gives 12 — it does not round up.

Example 7 — Student Marks

dart
void main() {
  var student = 'Ali';
  var math = int.parse('80');
  var science = int.parse('75');
  var english = int.parse('85');
  var total = math + science + english;
  var average = total / 3;
  print('Student: $student');
  print('Total: $total');
  print('Average: $average');
  print('Average type: ${average.runtimeType}');
}
output
Student: Ali
Total: 240
Average: 80.0
Average type: double

How it works

  1. Each mark arrives as text and int.parse turns it into an int.
  2. total adds three int values, so it is an int.
  3. Dividing with / always gives a double, which runtimeType confirms.

Example 8 — Shopping Total

dart
void main() {
  var product = 'Headphones';
  var price = double.parse('499.99');
  var quantity = int.parse('2');
  var total = price * quantity;
  print('Product: $product');
  print('Total: $total');
  print('Without paisa: ${total.toInt()}');
}
output
Product: Headphones
Total: 999.98
Without paisa: 999

How it works

  1. The price text has a decimal point, so it needs double.parse.
  2. The quantity is a whole number, so int.parse is enough.
  3. toInt() cuts off .98, giving 999.

Example 9 — Bank Balance

dart
void main() {
  var balance = 1000.0;
  var depositText = '250.75';
  var deposit = num.parse(depositText);
  balance = balance + deposit;
  print('Deposit is a double: ${deposit is double}');
  print('Deposit is not an int: ${deposit is! int}');
  print('Balance: $balance');
}
output
Deposit is a double: true
Deposit is not an int: true
Balance: 1250.75

How it works

  1. Sara types her deposit, so it arrives as the text '250.75'.
  2. num.parse turns it into a number — here a double, because the text has a decimal point.
  3. Adding it to the double balance gives 1250.75.

Example 10 — Temperature Conversion

dart
void main() {
  var celsius = int.parse('30');
  var fahrenheit = celsius * 9 / 5 + 32;
  print('Celsius: $celsius (${celsius.runtimeType})');
  print('Fahrenheit: $fahrenheit (${fahrenheit.runtimeType})');
  print('Rounded: ${fahrenheit.toInt()}');
}
output
Celsius: 30 (int)
Fahrenheit: 86.0 (double)
Rounded: 86

How it works

  1. int.parse('30') gives the int 30.
  2. The / in the formula makes fahrenheit a double: 86.0.
  3. toInt() turns 86.0 into the whole number 86.

Common Beginner Mistakes

1. Calculating with text

dart
void main() {
  var input = '25';
  // var next = input + 1; // ✗
}
output
Error: A value of type 'int' can't be assigned to a variable of type 'String'.

input is a String. Parse it first: int.parse(input) + 1.

2. Joining text and a number with +

dart
void main() {
  var age = 20;
  // print('Age: ' + age); // ✗
}
output
Error: A value of type 'int' can't be assigned to a variable of type 'String'.

Use interpolation, 'Age: $age', which converts the number for you.

3. Parsing a decimal with int.parse

dart
void main() {
  // var price = int.parse('99.5'); // ✗ crashes while running
}
output
Unhandled exception:
FormatException: Invalid radix-10 number (at character 1)
99.5
^

Use double.parse for text with a decimal point, or num.parse if it may be either.

4. Putting an int variable into a double

dart
void main() {
  int marks = 80;
  // double average = marks; // ✗
}
output
Error: A value of type 'int' can't be assigned to a variable of type 'double'.

A whole-number literal such as double x = 80; is allowed (Lecture 004), but an int variable is not. Write double average = marks.toDouble();.

5. Using as to convert

dart
void main() {
  num marks = 80;
  // double average = marks as double; // ✗ crashes while running
}
output
Unhandled exception:
type 'int' is not a subtype of type 'double' in type cast

as only relabels a value that already has the type. To change an int into a double, use toDouble().

6. Doing arithmetic with a tryParse result

dart
void main() {
  var count = int.tryParse('5');
  // print(count + 1); // ✗
}
output
Error: Operator '+' cannot be called on 'int?' because it is potentially null.

tryParse may return null, and Dart protects you from adding to "no value". When you are sure the text is a number, use parse. Handling the null safely comes in Lectures 012–015.

7. Expecting toInt() to round

9.99.toInt() is 9, not 10. Use round() when you want the nearest whole number.


Best Practices

  • Use runtimeType to explore and debug; use is to test a type.
  • Parse text into numbers as soon as it enters your program, then work with numbers.
  • Pick the parser that matches the text: int.parse for whole numbers, double.parse for decimals, num.parse when either is possible.
  • Use tryParse when the text comes from a person and may be mistyped.
  • Prefer interpolation ('Total: $total') over joining text and toString() with +.
  • Use as only when you are certain of the value's type — never as a converter.
  • Choose toInt() or round() on purpose; they give different answers.

Mini Challenge

Zayan counts the money in his piggy bank and writes the amounts on paper as text: '150' rupees from his birthday and '75' rupees from his uncle. Parse both, add them, and print the total, its type, and the total as a double.

Your program should print exactly:

output
Total: 225
Type: int
As double: 225.0

Try it yourself before opening the solution.

Show solution
dart
void main() {
  var birthday = int.parse('150');
  var uncle = int.parse('75');
  var total = birthday + uncle;
  print('Total: $total');
  print('Type: ${total.runtimeType}');
  print('As double: ${total.toDouble()}');
}
output
Total: 225
Type: int
As double: 225.0

How it works

  1. int.parse turns both pieces of text into int values.
  2. Adding two int values gives an int: 225.
  3. toDouble() produces the new value 225.0; total itself stays an int.

Practice Questions

Work through these in order — they run from beginner to application to challenge. Every question gives you exact values, so you can compare your output with the answers.

Beginner

  1. Store var name = 'Sara'; and var marks = 92.5;, then print the runtimeType of each, each on its own line.
  2. Declare num value = 10; and print the results of value is int and value is! int.
  3. Convert the text '48' to an int with int.parse, add 2, and print the result.

Application

  1. Convert the text '3.75' to a double, multiply it by 4, and print the result.
  2. Print the runtimeType of num.parse('100') and of num.parse('100.5').
  3. Print the results of int.tryParse('12') and int.tryParse('12a').
  4. Store var price = 1499.99;. Print it as a whole number twice: once with toInt() and once with round().
  5. Store var score = 45; and convert it to text with toString(). Print score + score, then the text joined to itself with +, then the type of the text.

Challenge

  1. Ali's three test marks arrive as the text values '70', '85', and '90'. Parse them, calculate the total and the average, and print Total: 245 and the average. Then print the average converted to a whole number with toInt().

  2. This program crashes while running. Fix it by changing one word, so that it prints 20.0:

    dart
    void main() {
      num temperature = 20;
      double reading = temperature as double;
      print(reading);
    }

Practice Answers

Question 1 — Solution

dart
void main() {
  var name = 'Sara';
  var marks = 92.5;
  print(name.runtimeType);
  print(marks.runtimeType);
}
output
String
double

Question 2 — Solution

dart
void main() {
  num value = 10;
  print(value is int);
  print(value is! int);
}
output
true
false

Question 3 — Solution

dart
void main() {
  var number = int.parse('48');
  print(number + 2);
}
output
50

Question 4 — Solution

dart
void main() {
  var amount = double.parse('3.75');
  print(amount * 4);
}
output
15.0

The result is a double, so it prints with .0.

Question 5 — Solution

dart
void main() {
  print(num.parse('100').runtimeType);
  print(num.parse('100.5').runtimeType);
}
output
int
double

Question 6 — Solution

dart
void main() {
  print(int.tryParse('12'));
  print(int.tryParse('12a'));
}
output
12
null

'12a' is not a whole number, so tryParse returns null instead of crashing.

Question 7 — Solution

dart
void main() {
  var price = 1499.99;
  print(price.toInt());
  print(price.round());
}
output
1499
1500

toInt() drops the decimal part; round() goes to the nearest whole number.

Question 8 — Solution

dart
void main() {
  var score = 45;
  var scoreText = score.toString();
  print(score + score);
  print(scoreText + scoreText);
  print(scoreText.runtimeType);
}
output
90
4545
String

The number adds up to 90; the text simply joins into 4545.

Question 9 — Solution

dart
void main() {
  var test1 = int.parse('70');
  var test2 = int.parse('85');
  var test3 = int.parse('90');
  var total = test1 + test2 + test3;
  var average = total / 3;
  print('Total: $total');
  print('Average: $average');
  print('Whole average: ${average.toInt()}');
}
output
Total: 245
Average: 81.66666666666667
Whole average: 81

/ gives a double, and 245 / 3 does not divide evenly, so Dart prints many decimal places. toInt() keeps only the 81.

Question 10 — Solution

20 is an int, so the cast to double fails. Replace the cast with a conversion:

dart
void main() {
  num temperature = 20;
  double reading = temperature.toDouble();
  print(reading);
}
output
20.0

Quick Revision

  1. What does runtimeType tell you?
  2. If num x = 5;, what does x.runtimeType print?
  3. What is the difference between is and is!?
  4. Does as convert a value? What happens if the cast is wrong?
  5. Which parser would you use for '42'? For '4.2'? For text that could be either?
  6. What does int.tryParse('abc') return?
  7. What does 7.9.toInt() give, and how is that different from 7.9.round()?
  8. How do you turn the number 30 into the text '30'?

Key Takeaways

  • runtimeType shows the type of the value, which may be more specific than the variable's declared type.
  • is and is! test a type and answer with a bool.
  • as is a cast: it treats a value as a type it already has, and crashes if it doesn't.
  • int.parse, double.parse, and num.parse turn text into numbers; invalid text stops the program with a FormatException.
  • tryParse returns null instead of crashing when the text is not a number.
  • toString() turns a number into text; interpolation does this for you.
  • toDouble() turns an int into a double; toInt() drops the decimal part of a double.
  • Conversion always creates a new value — the original is unchanged.

What's Next?

Lecture 11 — dynamic vs Object. In this lecture we checked and cast values stored in num variables, where we always knew the choice was int or double. Some variables can hold values of any type at all. Next we will meet dynamic and Object, see how they differ, and see why is and as matter even more with them.


Video lecture

Subscribe
Placeholder video — the real recording isn't linked yet.