Look out for the comment written 'error is here'. The compiler should throw an error if the types don't match, but it doesn't. The variable type is a boolean and I have passed in a string as the value. As such, their should be an error thrown that the types do not match.
class CompanyPreferences {
late bool editHistory;
late bool showOrderReference;
late bool canBeOffline;
late bool hasCancel;
late bool hasSkip;
late bool homepagePickup;
late double geofenceDistance;
late bool viewPendingOrders;
CompanyPreferences({
this.editHistory = true,
this.showOrderReference = false,
this.canBeOffline = false,
this.hasCancel = true,
this.hasSkip = true,
this.homepagePickup = false,
this.geofenceDistance = 0.0,
this.viewPendingOrders = false,
});
factory CompanyPreferences.fromMap(Map<String, dynamic> map) {
return CompanyPreferences(
editHistory: map["preference_data"]["driver_app"] == null ? true : map["preference_data"]["driver_app"]['edit_history'] ?? true,
showOrderReference: map["preference_data"]["driver_app"] == null ? false : map["preference_data"]["driver_app"]['show_order_reference'] ?? false,
canBeOffline: map["preference_data"]["driver_app"] == null ? false : map["preference_data"]["driver_app"]['can_be_offline'] ?? false,
hasCancel: map["preference_data"]["driver_app"] == null ? false : map["preference_data"]["driver_app"]['has_cancel'] ?? false,
hasSkip: map["preference_data"]["driver_app"] == null ? false : map["preference_data"]["driver_app"]['has_skip'] ?? false,
homepagePickup: map["preference_data"]["driver_app"] == null ? false : map["preference_data"]["driver_app"]['homepage_pickup'] ?? false,
geofenceDistance: map["preference_data"]["driver_app"] == null
? 0.0
: map["preference_data"]["driver_app"]['geofence_distance'] == null
? 0.0
: map["preference_data"]["driver_app"]['geofence_distance'].toDouble(),
// Error is here. The compiler doesn't throw an error.
viewPendingOrders: map["preference_data"]["driver_app"] == null ? "ERROR IS HERE" : map["preference_data"]["driver_app"]['view_pending_orders'] ?? false,
);
}
}
CodePudding user response:
Distilling your problem down a bit:
Type staticType<T>(T object) => T;
void main() {
var map = <String, dynamic>{};
var x = map['foo'] == null ? 'string' : map['bar'] ?? false;
print(staticType(x)); // Prints: dynamic
}
The problem is that map['bar']
has type dynamic
and basically poisons the rest of the conditional ternary expression.
The "then" part of the conditional expression is of type String
, and the "else" part has a ??
expression. The result of that ??
expression can either be the dynamic
type on the left side or the bool
type on the right. The ??
expression thus is determined to have a static type of the nearest common base type of dynamic
and bool
, which is dynamic
. Similarly, the type of the conditional ternary expression will be the nearest common base type of String
and dynamic
, which again will be dynamic
.
Since the entire conditional ternary expression will be of type dynamic
, it will not be type-checked when passing it as a bool
argument.