Skip to content

Allow static members to reference type parameters of the class #34415

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

Open
Hixie opened this issue Sep 10, 2018 · 5 comments
Open

Allow static members to reference type parameters of the class #34415

Hixie opened this issue Sep 10, 2018 · 5 comments
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language).

Comments

@Hixie
Copy link
Contributor

Hixie commented Sep 10, 2018

I have a class of type Foo<T> on which I want to call a static method to build a Foo<T> using a source of R values and a callback that can convert Rs to Ts.

   typedef T Converter<R, T>(R value);
   class Foo<T> {
     static Foo<T> convert<R>(Bar<R> source, Converter<R, T> converter) {
       // ...
     }
   }

I would call this as Foo<X>.convert<Y>(...).

This fails with Error: Static members can't reference type parameters of the class.

@Hixie
Copy link
Contributor Author

Hixie commented Sep 10, 2018

(Using a constructor instead fails with #34414.)

@Hixie
Copy link
Contributor Author

Hixie commented Sep 10, 2018

(I worked around the issue by calling it convert<T, R>, but that seems less idiomatic.)

@matanlurey matanlurey added the area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). label Sep 10, 2018
@sm-tester
Copy link

I have the same issue:

class CantCast implements Exception {
	String cause;

	CantCast(this.cause);
}

abstract class Enum<T> {

	final T _value;

	const Enum(this._value);

	T get value => _value;
}

class Currency<String> extends Enum<String> {
	const Currency(String val) : super (val);
	static const Currency USD = const Currency("USD");
	static const Currency SOUM = const Currency("SOUM");

	static Currency byValue(String src) {
		if (src == USD.value) return USD;
		if (src == SOUM.value) return SOUM;
		throw Currency("Can't cast to Currency, src: $src");
	}
}

image

@natebosch
Copy link
Member

@Boyfox - you want class Currency extends Enum<String>.

@SuTechs
Copy link

SuTechs commented Mar 23, 2022

I am trying to create an abstract class with all the common functions so that code repetition is less. For e.g I have two model classes TestModel and TestModel1 with the same functionality of adding, getting data to Firestore but with different attributes mainly name and name1.
Now i wanna do TestModel.get() to get all the data stored or TestModel.add(data) to add data. But the problem is Static members can't reference type parameters of the class.
Now is there any workaround to the problem or some better way to achieve what I'm trynna do. Please refer below code for the details.

abstract class Database<T> {
  /// constants
  static final testModelName = 'TestModelName';
  static final testModelName1 = 'TestModelName1';

  /// constructor
  Database(String collectionName) {
    ref =
        FirebaseFirestore.instance.collection(collectionName).withConverter<T>(
              fromFirestore: (snapshot, _) => fromJson(snapshot.data()!),
              toFirestore: (t, _) => toJson(),
            );
  }

  static late final CollectionReference<T>
      ref; // Static members can't reference type parameters of the class.

  /// json serialization
  Map<String, dynamic> toJson();

  T fromJson(Map<String, dynamic> json);

  /// helper function

  static Future<List<T>> get() async {
    // Static members can't reference type parameters of the class.
    return (await ref.get()).docs.map((e) => e.data()).toList();
  }

  static Future<void> add(T data) async {
    // Static members can't reference type parameters of the class.
    await ref.add(data);
  }
}

class TestModel extends Database<TestModel> {
  TestModel(this.id, this.name) : super(Database.testModelName);

  final String id;
  final String name;

  @override
  Map<String, dynamic> toJson() => {
        'id': id,
        'name': name,
      };

  @override
  TestModel fromJson(Map<String, dynamic> json) =>
      TestModel(json['id'], json['name']);
}

class TestModel1 extends Database<TestModel1> {
  TestModel1(this.id, this.name, this.name1) : super(Database.testModelName1);

  final String id;
  final String name;
  final String name1;

  @override
  Map<String, dynamic> toJson() => {
        'id': id,
        'name': name,
        'name1': name1,
      };

  @override
  TestModel1 fromJson(Map<String, dynamic> json) =>
      TestModel1(json['id'], json['name'], json['name1']);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language).
Projects
None yet
Development

No branches or pull requests

5 participants