On this page26 sections
- Prerequisites
- Connection With Previous Lectures
- Learning Objectives
- 1. What Are Type Checking and Conversion?
- 2. Asking a Value Its Type: runtimeType
- 3. runtimeType Shows the Value, Not the Label
- 4. Checking a Type with is
- 5. The Opposite Check: is!
- 6. Casting with as
- 7. When as Is Wrong
- 8. Text to Whole Number: int.parse
- 9. double.parse and num.parse
- 10. When Parsing Fails
- 11. Safe Parsing with tryParse
- 12. Number to Text: toString
- 13. Between int and double: toInt and toDouble
- 14. A Real-World Example
- Code Examples
- Common Beginner Mistakes
- Best Practices
- Mini Challenge
- Practice Questions
- Practice Answers
- Quick Revision
- Key Takeaways
- What's Next?
Lecture 10 — Type Checking & Conversion
| Category | 2 — Variables & Data Types |
| Lecture | 010 of 140 |
| Estimated video length | 11 min |
| Target | Dart 3.12.2 |
| Level | Beginner |
The text
'25'and the number25look 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, andlate- the types
String,int,double,num, andbool - string interpolation with
$and${}, and joining strings with+ - arithmetic with
intanddouble, and why/always gives adouble
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:
void main() {
var quantityText = '3';
// var next = quantityText + 1; // ✗ a String cannot be added to an int
print(quantityText);
}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
isandis! - Treat a
numas a more specific type withas - Convert text to numbers with
int.parse,double.parse, andnum.parse - Use
tryParseto convert text that may not be a valid number - Convert numbers to text with
toString - Convert between
intanddoublewithtoIntandtoDouble - 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:
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);
}String
int
double
boolThis 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:
void main() {
num price = 100;
print(price.runtimeType);
price = 99.5;
print(price.runtimeType);
}int
doubleThe 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:
void main() {
num score = 25;
print(score is int);
print(score is double);
}true
falsescore 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:
void main() {
num temperature = 36.6;
print(temperature is! int);
print(temperature is! double);
}true
false36.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:
void main() {
num reading = 36.6;
double temperature = reading as double;
print(temperature);
}36.6Without 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:
void main() {
num marks = 80;
double average = marks as double;
print(average);
}Unhandled exception:
type 'int' is not a subtype of type 'double' in type cast80 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:
void main() {
var quantityText = '3';
var quantity = int.parse(quantityText);
print(quantity + 1);
print(quantity.runtimeType);
}4
intThe 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:
void main() {
print(double.parse('99.5'));
print(double.parse('5'));
print(num.parse('42').runtimeType);
print(num.parse('3.5').runtimeType);
}99.5
5.0
int
doubledouble.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:
void main() {
var age = int.parse('twenty');
print(age);
}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":
void main() {
var good = int.tryParse('42');
var bad = int.tryParse('forty-two');
print(good);
print(bad);
print(double.tryParse('7.25'));
}42
null
7.25The 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:
void main() {
var age = 20;
var ageText = age.toString();
print(age + age);
print(ageText + ageText);
print(ageText.runtimeType);
}40
2020
StringSame 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:
void main() {
var marks = 80;
var price = 9.99;
print(marks.toDouble());
print(price.toInt());
print(price.round());
}80.0
9
10toInt() 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:
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}');
}Price is a double: true
Quantity type: int
Total: 1351.5
Whole rupees: 1351
Saved as: Stringnum.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
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);
}String
int
double
boolExample 2 — is and is!
void main() {
num amount = 250;
print(amount is int);
print(amount is double);
print(amount is! double);
}true
false
trueExample 3 — Casting a num
void main() {
num height = 5.9;
double heightInFeet = height as double;
print(heightInFeet);
print(heightInFeet.runtimeType);
}5.9
doubleExample 4 — Parsing Whole and Decimal Numbers
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);
}22
63.0Example 5 — num.parse and tryParse
void main() {
print(num.parse('15').runtimeType);
print(num.parse('15.0').runtimeType);
print(int.tryParse('15'));
print(int.tryParse('fifteen'));
}int
double
15
nullExample 6 — toString, toInt, toDouble
void main() {
var count = 7;
var distance = 12.8;
print(count.toString().runtimeType);
print(count.toDouble());
print(distance.toInt());
}String
7.0
12How it works
count.toString()makes the text'7', so its type isString.count.toDouble()makes thedouble7.0.distance.toInt()drops.8and gives12— it does not round up.
Example 7 — Student Marks
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}');
}Student: Ali
Total: 240
Average: 80.0
Average type: doubleHow it works
- Each mark arrives as text and
int.parseturns it into anint. totaladds threeintvalues, so it is anint.- Dividing with
/always gives adouble, whichruntimeTypeconfirms.
Example 8 — Shopping Total
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()}');
}Product: Headphones
Total: 999.98
Without paisa: 999How it works
- The price text has a decimal point, so it needs
double.parse. - The quantity is a whole number, so
int.parseis enough. toInt()cuts off.98, giving999.
Example 9 — Bank Balance
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');
}Deposit is a double: true
Deposit is not an int: true
Balance: 1250.75How it works
- Sara types her deposit, so it arrives as the text
'250.75'. num.parseturns it into a number — here adouble, because the text has a decimal point.- Adding it to the
doublebalancegives1250.75.
Example 10 — Temperature Conversion
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()}');
}Celsius: 30 (int)
Fahrenheit: 86.0 (double)
Rounded: 86How it works
int.parse('30')gives theint30.- The
/in the formula makesfahrenheitadouble:86.0. toInt()turns86.0into the whole number86.
Common Beginner Mistakes
1. Calculating with text
void main() {
var input = '25';
// var next = input + 1; // ✗
}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 +
void main() {
var age = 20;
// print('Age: ' + age); // ✗
}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
void main() {
// var price = int.parse('99.5'); // ✗ crashes while running
}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
void main() {
int marks = 80;
// double average = marks; // ✗
}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
void main() {
num marks = 80;
// double average = marks as double; // ✗ crashes while running
}Unhandled exception:
type 'int' is not a subtype of type 'double' in type castas 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
void main() {
var count = int.tryParse('5');
// print(count + 1); // ✗
}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
runtimeTypeto explore and debug; useisto 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.parsefor whole numbers,double.parsefor decimals,num.parsewhen either is possible. - Use
tryParsewhen the text comes from a person and may be mistyped. - Prefer interpolation (
'Total: $total') over joining text andtoString()with+. - Use
asonly when you are certain of the value's type — never as a converter. - Choose
toInt()orround()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:
Total: 225
Type: int
As double: 225.0Try it yourself before opening the solution.
Show solution
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()}');
}Total: 225
Type: int
As double: 225.0How it works
int.parseturns both pieces of text intointvalues.- Adding two
intvalues gives anint:225. toDouble()produces the new value225.0;totalitself stays anint.
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
- Store
var name = 'Sara';andvar marks = 92.5;, then print theruntimeTypeof each, each on its own line. - Declare
num value = 10;and print the results ofvalue is intandvalue is! int. - Convert the text
'48'to anintwithint.parse, add2, and print the result.
Application
- Convert the text
'3.75'to adouble, multiply it by4, and print the result. - Print the
runtimeTypeofnum.parse('100')and ofnum.parse('100.5'). - Print the results of
int.tryParse('12')andint.tryParse('12a'). - Store
var price = 1499.99;. Print it as a whole number twice: once withtoInt()and once withround(). - Store
var score = 45;and convert it to text withtoString(). Printscore + score, then the text joined to itself with+, then the type of the text.
Challenge
-
Ali's three test marks arrive as the text values
'70','85', and'90'. Parse them, calculate the total and the average, and printTotal: 245and the average. Then print the average converted to a whole number withtoInt(). -
This program crashes while running. Fix it by changing one word, so that it prints
20.0:void main() { num temperature = 20; double reading = temperature as double; print(reading); }
Practice Answers
Question 1 — Solution
void main() {
var name = 'Sara';
var marks = 92.5;
print(name.runtimeType);
print(marks.runtimeType);
}String
doubleQuestion 2 — Solution
void main() {
num value = 10;
print(value is int);
print(value is! int);
}true
falseQuestion 3 — Solution
void main() {
var number = int.parse('48');
print(number + 2);
}50Question 4 — Solution
void main() {
var amount = double.parse('3.75');
print(amount * 4);
}15.0The result is a double, so it prints with .0.
Question 5 — Solution
void main() {
print(num.parse('100').runtimeType);
print(num.parse('100.5').runtimeType);
}int
doubleQuestion 6 — Solution
void main() {
print(int.tryParse('12'));
print(int.tryParse('12a'));
}12
null'12a' is not a whole number, so tryParse returns null instead of crashing.
Question 7 — Solution
void main() {
var price = 1499.99;
print(price.toInt());
print(price.round());
}1499
1500toInt() drops the decimal part; round() goes to the nearest whole number.
Question 8 — Solution
void main() {
var score = 45;
var scoreText = score.toString();
print(score + score);
print(scoreText + scoreText);
print(scoreText.runtimeType);
}90
4545
StringThe number adds up to 90; the text simply joins into 4545.
Question 9 — Solution
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()}');
}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:
void main() {
num temperature = 20;
double reading = temperature.toDouble();
print(reading);
}20.0Quick Revision
- What does
runtimeTypetell you? - If
num x = 5;, what doesx.runtimeTypeprint? - What is the difference between
isandis!? - Does
asconvert a value? What happens if the cast is wrong? - Which parser would you use for
'42'? For'4.2'? For text that could be either? - What does
int.tryParse('abc')return? - What does
7.9.toInt()give, and how is that different from7.9.round()? - How do you turn the number
30into the text'30'?
Key Takeaways
runtimeTypeshows the type of the value, which may be more specific than the variable's declared type.isandis!test a type and answer with abool.asis a cast: it treats a value as a type it already has, and crashes if it doesn't.int.parse,double.parse, andnum.parseturn text into numbers; invalid text stops the program with aFormatException.tryParsereturnsnullinstead of crashing when the text is not a number.toString()turns a number into text; interpolation does this for you.toDouble()turns anintinto adouble;toInt()drops the decimal part of adouble.- 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.