Skip to content

Unable to Create Generic Constructor of T that extends a concrete Type #47699

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
indrajit-roy opened this issue Nov 15, 2021 · 4 comments
Closed
Labels
area-sdk Use area-sdk for general purpose SDK issues (packaging, distribution, …). closed-duplicate Closed in favor of an existing report

Comments

@indrajit-roy
Copy link

Hi. Today I faced an issue when I wanted to create a parent data class for all my data models in dart.
What I am trying to do,

abstract class DataClass {
// throwing an error since abstract classes cannot be instantiated, 
// but I need my sub classes to implement this factory constructor
 factory DataClass.fromMap(Map<String, dynamic> map) => throw UnimplementedError();
} 
class ModelClass<T extends DataClass> extends DataClass {
final List<T> values;
factory ModelClass.fromMap(Map<String, dynamic> json) => ModelClass(     
       // Cannot call a constructor invokation on T
        values: json["results"] == null ? null : List<T>.from(json["values"].map((x) => T.fromMap(x))),
      );
}

I dont know if there is another way of achieving a similar outcome. But implementing something like this would drastically reduce a lot of Api Response duplication, where some parameters are always constant.

@keertip keertip added the area-sdk Use area-sdk for general purpose SDK issues (packaging, distribution, …). label Nov 15, 2021
@keertip
Copy link
Contributor

keertip commented Nov 15, 2021

@leafpetersen

@eernstg
Copy link
Member

eernstg commented Nov 15, 2021

Note that the ability to invoke static methods and/or constructors of a class based on the value of a type variable was discussed in #10667 and dart-lang/language#356.

@lrhn lrhn added the closed-duplicate Closed in favor of an existing report label Jul 2, 2022
@lrhn
Copy link
Member

lrhn commented Jul 2, 2022

Closing in favor of dart-lang/language#356.

@lrhn lrhn closed this as completed Jul 2, 2022
@eernstg
Copy link
Member

eernstg commented Jul 4, 2022

Let me just mention the standard workaround for being able to call a constructor of a type variable: Introduce a formal parameter which is a factory function (which would typically be the torn-off constructor, but could also be any other function with the right type), and then call that factory function rather than trying to call a constructor on a type variable:

abstract class DataClass {
  DataClass.fromMap(Map<String, dynamic> map);
}

class ModelClass<T extends DataClass> extends DataClass {
  final List<T>? values;
  ModelClass.fromMap(
      Map<String, dynamic> json, T Function(Map<String, dynamic>) tFactory)
      : values = json["results"] == null ? null : <T>[],
        super.fromMap(json) {
    var values = this.values;
    if (values != null) {
      Iterable<Map<String, dynamic>> jsonValues = json["values"]!;
      for (var x in jsonValues) {
        values.add(tFactory(x));
      }
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-sdk Use area-sdk for general purpose SDK issues (packaging, distribution, …). closed-duplicate Closed in favor of an existing report
Projects
None yet
Development

No branches or pull requests

4 participants