How to enforce Implements constraint on generic type T in generic Dart method?
1,073
Problem
It seems like I can't set an implements constraint on type T, only an extends. For example <T implements IModel does not work but works.
This is not a problem. You can safely use <T extends IModel>
, even for classes that implements IModel
:
abstract class Abstract {}
class Concrete implements Abstract {}
void function<T extends Abstract>(T value) {
print(value);
}
void main() {
function<Concrete>(Concrete()); // works
}
Author by
EggBender
Updated on December 23, 2022Comments
-
EggBender over 1 year
What I'm trying to achieve
I am trying to create a generic Dart method that takes a generic type T where T has to implement class IModel. However,
Problem
It seems like I can't set an
implements
constraint on type T, only anextends
. For example<T implements IModel
does not work but<T extends IModel>
works.Code
IModel.dart which serves as an interface:
class IModel { IModel(); factory IModel.fromJson(Map<String, dynamic> json) { return IModel(); } Map<String, dynamic> toJson() => {}; IModel clone() { return IModel(); } }
MyModel.dart, an example that implements IModel:
import 'dart:core'; import 'package:.../helpers/DateTimeHelper.dart'; import 'package:.../helpers/StringHelper.dart'; import 'package:.../models/IModel.dart'; class MyModel implements IModel { String id; String name; String companyId; String projectId; String description; DateTime created; DateTime updated; MyModel({this.id, this.name, this.description, this.created, this.updated, this.companyId, this.projectId}); factory MyModel.fromJson(Map<String, dynamic> json) { return MyModel(id: json["id"], name: json["name"], created: DateTime.parse(json["created"]), updated: DateTime.parse(json["updated"]), description: json["description"], companyId: json["companyId"], projectId: json["projectId"]); } Map<String, dynamic> toJson() => { "Id": id, "Name": name, "Description": description, "CompanyId": companyId, "ProjectId": projectId, "Created": created.toIso8601String(), "Updated": updated.toIso8601String() }; MyModel clone() { return new MyModel(id: StringHelper.clone(id), companyId: StringHelper.clone(companyId), created: DateTimeHelper.clone(created), updated: DateTimeHelper.clone(updated), name: StringHelper.clone(name), projectId: StringHelper.clone(projectId), description: StringHelper.clone(description)); } }
ModelHelper.dart with the generic method:
import 'dart:convert'; import 'package:.../models/IModel.dart'; // 'T implements IModel' not working, but 'T extends IModel' does as constraint. abstract class ModelHelper { static List<T> listFromJson<T implements IModel>(String json) { List l = jsonDecode(json)["data"]; var models = l.map((m) => T.fromJson(m)).toList(); return models; } }
Additional questions/conclusion
Are
implements
constraints not supported in Dart? Do all T classes simply have to extend IModel?