×

Type System in Dart

Dart language is a type safety enabled language that uses static and dynamic type checking to match the value of the variable with its data type at the compile-time. This is also known as sound typing. Although the types are mandatory, data type annotations are optional because of the type interference.

The static type checking is really advantageous as it has the ability to find the errors at the compile time using the static analyser of Dart. Most of the bugs interpreted by the static analyser can be fixed by declaring the generic classes along with the type annotations.

The most common generic classes are the collection types which are as follows :

  1. List< T >
  2. Map< K, V >.

For example, in the following code the int_list( ) function prints an integer list, and main( ) functions creates a list and passes it to the int_list( ) function.

Consider the following code in Dart that uses collection types :

Example – 1 :

void int_list( List< int > a) => print( a ) ;
void main( ) 
{
  var list = [ ] ;
  list.add( 5 ) ;
  list.add( ' Yukta ' ) ;
  int_list( list ) ;
}

Output :

The code did not compile as it resulted in a type error on the list when the function int_list( ) function is called.

Error :

Error compiling to JavaScript:
Info: Compiling with sound null safety
Warning: Interpreting this as package URI, 'package:dartpad_sample/main.dart'.
lib/main.dart:7:13:
Error: The argument type 'List<dynamic>' can't be assigned to the parameter type 'List<int>'.
 - 'List' is from 'dart:core'.
  int_list( list ) ;
            ^
Error: Compilation failed.

The error highlights an unsound implicit cast from List< dynamic > to List< int >. The list variable has static type List< dynamic >. The definition of the list as

var list = [   ] 

does not provide clear information to the type analyzer to interpret the type argument more specific than dynamic. The int_list( ) function expects a parameter of type List< int >, causing a mismatch of types.

Let us try to debug the above code.

We must begin with specifying a type annotation ( < int > ) while defining that list. It should be like :

var list = < int >[  ] ;

But still, the problem isn't solved completely.  The analyzer throws an error that the string type value can not be assigned to the integer type parameters as in the line :

list.add( ' Yukta ' ) ;

To solve this problem as well, we must add only the integer value like :

list.add( 2 ) ;

This will result in code passing static analysis and running with no errors or warnings.

void int_list( List< int > num ) => print( num ) ;
void main( ) 
{
  var list = < int >[  ] ;
  
  // adding the integer elements to the list
  list.add( 5 ) ;
  list.add( 10 ) ;
  list.add( 15 ) ;
  
  // printing the list
  int_list( list ) ;
}

Output :

[5, 10, 15]

What is soundness?

Soundness helps to ensure that the program successfully gets over the invalid states. A sound type system used in the program enables that the program never gets into a state where an expression is evaluated to a value that doesn't match the static type of the expression. For example, if an expression has a type ' String ' at the time of compilation, you are guaranteed only to get a string when you evaluate it at the run time.

Like in any other programming language such as Java and C#, the type system of Dart is sound. It enforces soundness using a combination of static checking ( compile - time errors ) and dynamic checking ( at runtime ). For example, assigning a String to int is a compile - time error. Casting an object to a String using as String fails with a runtime error if the object isn't a String.

The benefits of soundness

Sound type system has many benefits. Some of them are as follows :

  • Revealing type-related bugs at compile time : A sound type system ensures that the code is unambiguous with respect to the data types, such that the type - related bugs that might be difficult to find at runtime are successfully revealed at compile time.
  • More readable code: Code becomes more readable with the sound type safety because one can rely on a value actually having the exact specified data type. In sound Dart, types can’t lie.
  • More maintainable code : With a sound type system, whenever a piece of code is changed let us say the data type of a variable, the type system highlights and warns the programmer about the other places where the data type is still the old one.
  • Better ahead of time (AOT) compilation: While AOT compilation is possible without types; the generated code is much less efficient.

Tips for passing static analysis

Most of the rules for static types are easy to understand. Here are some of the less obvious rules:

  • Use sound return types when overriding methods.
  • Use sound parameter types when overriding methods.
  • Don’t use a dynamic list as a typed list.

Related Topics

Dart Concurrency

Dart concurrency allows us to run multiple or multiple components of a system at once. It issues several commands at once. Dart provides Isolates as a tool for performing compliance...

2 minutes read.

Dart this Keyword

The ' this ' keyword, similar to that in Java and C#, refers to an object of the class using it. It points to the current object of the class,...

5 minutes read.

Dart Constants

Dart Constants are the objects or variables whose values can’t change or modify during the execution of the program. Their use case is when we want a particular value to...

2 minutes read.

Dart Optional Parameters

Dart functions can have optional parameters with default values. When we create a function, we can specify parameters that calling code can provide; but if the calling code chooses not...

2 minutes read.

Dart Equality and Relational Operators

Dart provides the functionality of checking the relationship between the values or values within the variables. These operators return the resultant value as Boolean, i.e., either ‘true’ or ‘false’. Some important points...

3 minutes read.

Dart Inheritance

Inheritance is a promising concept of any programming language. It is a property by which a class inherits the property of another class. Moreover, the class deriving the properties of...

5 minutes read.

Dart Future and Stream

Before understanding Future and Stream in Dart, we need first to get familiar with two terms : Synchronous and Asynchronous Programming.  In synchronous programming, a single operation is handled at a...

9 minutes read.

Dart Static Members

Static Members in Dart Static members are the members of the class declared using the 'static' keyword. the static members have the following characteristics :  All the objects of the class having...

3 minutes read.

Dart Classes

Dart is an object – oriented programming language that supports all the object-oriented programming concepts such as classes, objects, inheritance, data abstraction and data encapsulation. A class can be defined as...

8 minutes read.

Dart Logical Operators

Logical operators are the operators that combine two or more conditions, and accordingly return a Boolean value : true or false. Assume the value of variable A is 25 and B...

2 minutes read.

Common Collection Methods

Most of the programming languages have arrays as a way to list items together. However, Dart has a collection of data structures similar to array. These are supported by the...

3 minutes read.

Dart Assignment Operator

Assignment operators are the operators that assign value to the variables. The value on the right-hand side is assigned to the variable on the left-hand side. We can also use...

4 minutes read.

Dart Type Test Operators

Type Test Operators in Dart These operators are used to check the types of expressions at runtime. Dart is a typed language, and we often want to assert that a value...

1 minute read.

Dart Queues

A queue is a user-defined collection of data. It is based on the FIFO principle ( First In First Out ) which implies that the element to be inserted first,...

3 minutes read.

Dart If-else statement

In the previous section, we studied about if statements in detail. If – block is executed when the condition evaluates to true, else if the condition evaluates to false, then...

1 minute read.

Dart Recursion

Recursion is one of the most important and interesting concepts in any programming language. It can be defined as a process in which a function calls itself directly or indirectly....

5 minutes read.

Dart - extends, with and implements Keywords

The application development in Dart programming language using the Flutter framework, regularly experience different usage of the implements, extends and with keywords. Dart has full support for inheritance that is...

5 minutes read.

Dart Method Overriding

Before understanding method overriding, it is important to clear the concept of polymorphism. Polymorphism is derived from two Greek words 'Poly' which means many and 'morphs' which means many forms....

5 minutes read.

Dart Syntax

In the previous tutorial, we coded our first program in Dart on various platforms understanding the basic functionality of each line of code.  Let us understand the syntax for Dart language...

4 minutes read.

Unit Testing in Dart

Typing testing ensures that your app keeps working as you add more features or change existing functionality. Unit testing helps to confirm the behavior of a single function, method, or...

4 minutes read.