Charles Clayton
Charles Clayton

Reputation: 17956

Why are incorrect type assignments allowed in Dart?

I know that types are pretty much optional with Dart, but if I choose to specify the variable type, I expect an assignment like int i = "abc" to throw an error in runtime. However neither that nor any of the following throw an error, they just ignore the type cast.

  String str     = "test";
  int integer    = 5;
  double decimal = 1.5;
  List list      = [1,2,3];

  String s = decimal;   print(s);  // 1.5
  int i    = str;       print(i);  // test
  double d = list;      print(d);  // [1, 2, 3]
  List l   = integer;   print(l);  // 5

In this tutorial I found, it says:

But the snippet below generates an error because the compiler identifies b as an int that is wrongly being assigned a double value. This is type-checking in action, and one of the many ways that Dart improves on JavaScript.

int b=7898765;

b = 9.8; // ERROR Can't assign double to int

However, that code doesn't generate an error for me either when using Dartium or when using <script src="packages/browser/dart.js"></script>.

If I do var i = "abc" + 1.5, it throws an error, so why doesn't a type misassignment do the same? Is this an oversight or is it a design choice? If the latter, what's the reasoning?

Thanks in advance.

Upvotes: 3

Views: 523

Answers (2)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657356

This answer is Dart 1.x only

In Dart type annotations are just ignored when run in production mode (default). If you run in checked mode types are checked. If you call a non-existing method on an instance an exception is still thrown.

var i = "abc" + 1.5

the + operator (method) obviously does a type check on the argument and throws because it doesn't non-string values.

For JS generated from Dart you can configure the $dart2js transformer to produce "checked-mode" output by adding

transformers:
- $dart2js:
    checked: true

to your pubspec.yaml file (for more $dart2js options see Configuring the Built-in dart2js Transformer for Pub). This only takes effect if you build using pub build. If you use dart2js directly to generate JS pass the -c flag to create checked-mode output.

For code run on the server VM also pass the -c flag like

dart -c your_script.dart

In your question you didn't provide any information about how you run your Dart scripts or how you generate JS.

In this simple DartPad the editor shows errors from static analysis, which is another use-case for adding type annotations.

Upvotes: 2

ArtemGr
ArtemGr

Reputation: 12547

Dart 2.6 rejects this code.

A value of type 'double' can't be assigned to a variable of type 'String'

https://dartpad.dev/10ebe4bb74a11fe6e68efb351af40d1a

I've also tested with a Map<String, dynamic> (in order to better understand the JSON deserialization pattern)

void main() {
  Map<String, dynamic> map = {
    'str': 'test',
    'integer': 5,
    'decimal': 1.5,
    'list': [1,2,3]
  };

  String s = map['decimal'];   print(s);  // JSDouble not String
  int i    = map['str'];       print(i);  // JSString not int
  double d = map['list'];      print(d);  // JSArray not double
  List l   = map['integer'];   print(l);  // JSInt not List
}

https://dartpad.dev/7bc355b3b7779d2b37e1aae2b6def050

and this also fails at runtime, giving errors such as

TypeError: 1.5: type 'JSDouble' is not a subtype of type 'String'

Upvotes: 0

Related Questions