NNBD: Least upper bound of String and Null


Working on a patch for some issues in the Dart Analyzer, I need to understand whether Null itself is considered a nullable type.

Currently, the least upper bound computed by Dart’s type algebra for String and Null is String.

However, in my opinion, the type union of String and Null is a nullable String.

Ticket with patch: https://github.com/dart-lang/sdk/issues/38585 Note that the patch still has a bug in widening T to T? if a closure returns both T and null.

Bonus question (ticket https://github.com/dart-lang/sdk/issues/38623): Is Null itself a nullable type and should be suffixed with ‘?’?

My opinion as proof by contradiction (LUB is least upper bound function):

  • Assume that Null is not nullable.
  • That means Null and Null? are different types.
  • LUB(T, Null) = T?, i.e. combining T with Null widens T to T?
  • Hence, LUB(Null, Null) = Null?
  • That violates LUB being reflexive which would mean that LUN(Null, Null) = Null
  • Hence the assumption is wrong.


Dart does not, yet, have non-nullable types. So, the type written as String is a nullable string. The Null type is considered a subtype of any type, and therefore the least upper bound of Null and (nullable) String is (nullable) String.

When Dart gets non-nullable types, that will change. Then the type written String will be non-nullable, and String? will be nullable, and the least upper bound of Null and String should then (hopefully!) be String?. Non-nullable types are not yet available, but they are being designed and are expected to be released … well, when they are ready.

If you are trying to patch the Dart Analyzer, then you need to be aware of both type systems at the same tiem, because the analyzer has already been modified to recognize some non-nullable types if you pass the proper flags and proper source code.

Answered By – lrn

Answer Checked By – Mary Flores (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *