Given a type parameter T, the type T? is nullable version of T, i.e. A variable x of type
T? can either hold a value of type T or null.
However, when T itself is bound to a nullable type, a variable y of type T can hold a null
value by itself. For example, if y is defined as int?, null is a valid value for y.
Therefore, when T is bound to a nullable type, x can hold null as a valid value, which means that
x! is an incorrect check for the validity of x, since it would raise a runtime exception when x holds
null.
void main() {
int? x = null;
bangT(x); // Throws a runtime exception
asT(x); // Returns null
}
T bangT<T>(T x) => x!;
T asT<T>(T x) => x as T;