ZetCode

Type Conversions in Dart

last modified May 25, 2025

Dart is a statically typed language with a sound type system that handles type conversions differently than dynamically typed languages. This tutorial covers Dart's type conversion system including explicit casting, parsing, and conversion methods.

Dart Type Conversion Overview

Dart's type conversion system is designed to be explicit and type-safe. It allows you to convert between compatible types while preventing implicit conversions that could lead to runtime errors. The main conversion techniques include explicit casting, number parsing, string conversion, and type promotion.

Conversion Type Description Example
Explicit Casting Using as operator for type assertions var str = obj as String;
Number Parsing Converting strings to numbers int.parse('42')
String Conversion Converting to string representation 123.toString
Type Promotion Automatic in control flow if (obj is String) {...}

Key points about Dart casting:

Explicit Type Casting

Dart uses the as operator for explicit type casting between compatible types.

casting.dart
void main() {

  dynamic value = 'Hello Dart';
  
  // Safe casting with 'as'
  String str = value as String;
  print('String length: ${str.length}');
  
  // This would throw TypeError at runtime:
  // int number = value as int;
  
  // Safe casting with type check
  if (value is String) {
    print('Uppercase: ${value.toUpperCase()}');
  }
}

In Dart, casting is explicit and requires the as operator. This allows you to assert that a value is of a specific type. If the value is not compatible with the target type, a TypeError will be thrown at runtime.

$ dart run casting.dart
String length: 10
Uppercase: HELLO DART

Number Parsing and Conversion

Dart provides several ways to convert strings to numbers and between numeric types.

number_conversion.dart
void main() {

  // String to number
  int intVal = int.parse('42');
  double doubleVal = double.parse('3.14');
  
  // Number to string
  String intStr = 42.toString();
  String doubleStr = 3.14159.toStringAsFixed(2);
  
  // Between numeric types
  double d = 5; // int to double
  int i = 3.14.toInt(); // double to int (truncates)
  
  print('Parsed int: $intVal');
  print('Parsed double: $doubleVal');
  print('Int to string: $intStr');
  print('Formatted double: $doubleStr');
  print('Double to int: $i');
  
  // Safe parsing with tryParse
  int? maybeInt = int.tryParse('abc');
  print('TryParse result: $maybeInt');
}

The int.parse and double.parse methods convert strings to their respective numeric types. If the string cannot be parsed, a FormatException will be thrown. To avoid this, you can use tryParse, which returns null if parsing fails.

The toString method converts numbers to their string representation. You can also use toStringAsFixed to format decimal places, and toInt or toDouble to convert between numeric types. Dart does not allow implicit conversions between numeric types, so you must use these methods explicitly.

$ dart run number_conversion.dart
Parsed int: 42
Parsed double: 3.14
Int to string: 42
Formatted double: 3.14
Double to int: 3
TryParse result: null

String Conversion

Converting values to strings in Dart is straightforward with several options available.

string_conversion.dart
void main() {

  // Basic toString()
  String intStr = 42.toString();
  String boolStr = true.toString();
  
  // String interpolation automatically calls toString()
  String interpolated = 'Value: ${123}, Bool: ${false}';
  
  // More complex formatting
  String pi = 3.14159.toStringAsFixed(2);
  String hex = 255.toRadixString(16);
  
  print('intStr: $intStr');
  print('boolStr: $boolStr');
  print('interpolated: $interpolated');
  print('pi: $pi');
  print('hex: $hex');
}

The toString method is available on all objects in Dart, allowing you to convert any value to its string representation. Dart also supports string interpolation, which automatically calls the toString method on objects when used within a string. This makes it easy to create formatted strings from various types.

$ dart run string_conversion.dart
intStr: 42
boolStr: true
interpolated: Value: 123, Bool: false
pi: 3.14
hex: ff

Type Promotion in Dart

Dart automatically promotes types in certain control flow situations, providing type safety without explicit casting.

type_promotion.dart
void main() {

  dynamic value = 'Dart';
  
  // Type promotion in conditionals
  if (value is String) {
    print('Length: ${value.length}'); // value is now String
  }
  
  // Promotion with null checks
  String? maybeString;
  if (maybeString != null) {
    print('Length: ${maybeString.length}'); // maybeString is non-null
  }
  
  // Promotion with logical operators
  Object obj = 'Hello';
  if (obj is String && obj.length > 3) {
    print('Long string: $obj');
  }
}

Dart's type promotion works in is type checks, Null checks (!= null, == null), Logical expressions (&&, ||), and after exception catches.

$ dart run type_promotion.dart
Length: 4
Long string: Hello

Working with Collections

Dart provides methods to convert between different collection types.

collection_conversion.dart
import 'dart:collection';

void main() {

  // List conversions
  List<int> numbers = [1, 2, 3];
  List<String> strings = numbers.map((n) => n.toString()).toList();

  // Set from List
  Set<int> uniqueNumbers = numbers.toSet();

  // Map from List
  Map<int, String> map = {for (var n in numbers) n: 'Number $n'};

  // Convert to different collection types
  var fixedList = List<int>.unmodifiable(numbers);
  var linkedHashSet = LinkedHashSet<int>.from(numbers);

  print('Strings: $strings');
  print('Unique numbers: $uniqueNumbers');
  print('Map: $map');

  print('Fixed List: $fixedList');
  print('LinkedHashSet: $linkedHashSet');
}

The toList, toSet, and map methods provide convenient ways to convert between collections in Dart. You can also create new collections using constructors like List.from and Set.from.

$ dart run collection_conversion.dart
Strings: [1, 2, 3]
Unique numbers: {1, 2, 3}
Map: {1: Number 1, 2: Number 2, 3: Number 3}
Fixed List: [1, 2, 3]
LinkedHashSet: {1, 2, 3}

JSON Serialization

Dart provides built-in support for converting objects to/from JSON.

json_conversion.dart
import 'dart:convert';

// Custom objects need toJson/fromJson methods
class Language {
  final String name;
  final double version;

  Language(this.name, this.version);

  Map<String, dynamic> toJson() => {'name': name, 'version': version};

  factory Language.fromJson(Map<String, dynamic> json) {
    return Language(json['name'], json['version']);
  }
}

void main() {
    
  // Convert to JSON
  Map<String, dynamic> data = {'name': 'Dart', 'version': 2.19, 'isCool': true};
  String jsonStr = jsonEncode(data);

  // Parse from JSON
  Map<String, dynamic> decoded = jsonDecode(jsonStr);

  print('Original: $data');
  print('JSON: $jsonStr');
  print('Decoded: $decoded');

  Language dart = Language('Dart', 2.19);
  String langJson = jsonEncode(dart);
  Language decodedLang = Language.fromJson(jsonDecode(langJson));

  print('Language JSON: $langJson');
  print('Decoded language: ${decodedLang.name} ${decodedLang.version}');
}

The dart:convert library provides methods for JSON serialization and deserialization. It allows you to easily convert Dart objects to JSON strings and parse JSON strings back into Dart objects.

You can use the jsonEncode and jsonDecode methods for basic types, lists, and maps. For custom classes, you need to implement toJson and fromJson methods to handle serialization and deserialization. It works with primitive types, lists, and maps out of the box.

$ dart run json_conversion.dart
Original: {name: Dart, version: 2.19, isCool: true}
JSON: {"name":"Dart","version":2.19,"isCool":true}
Decoded: {name: Dart, version: 2.19, isCool: true}
Language JSON: {"name":"Dart","version":2.19}
Decoded language: Dart 2.19

Source

Dart Type System
Dart Language Tour: Conversion

Dart's type conversion system provides both safety through static typing and flexibility through explicit conversion methods. Understanding these conversion techniques is essential for writing robust Dart applications.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Dart tutorials.