dart-lang / dart-lang/language

Constructor specific generics

Open
#647 12 comments 67 reactions 0 assignees View on GitHub
feature
Dominant language
TeX
Stars
2.9k
Forks
239
Avg merge
2d 18h
Merged PRs (30d)
14

Description

A broader version of #276

## Problem

Currently, generic parameters are defined only on the class level.

But in some situations, a specific constructor may want extra generic parameters (which don't have an impact on `runtimeType`).

[Consumer] vs [Consumer2] or [Consumer] vs [Selector] from [provider] are good examples of such use-case.
Same thing with [ProxyProvider] vs [ProxyProvider2]

Currently, due to the lack of constructor specific generic parameters, the different options are split into different classes. But ultimately, the implementation of these different classes is _the same_.

An abstract example of how these duplicates currently work is:

```dart
abstract class _BaseClass {
_BaseClass(this.callback);
final Widget Function(BuildContext context) callback;
}

class Concrete1 extends _BaseClass {
Concrete1(Widget callback(BuildContext c, T value))
: super((c) => callback(c, doSomething(c));
}

class Concrete2 extends _BaseClass {
Concrete2(Widget callback(BuildContext c, T value, T2 value))
: super((c) => callback(c, doSomething(c), doSomethingElse(c));
}
```

### Proposal

The idea of this proposal is to allow _named constructors_ to have extra generic parameters:

```dart
class MyClass {
MyClass();
MyClass.named(B b);
}

void main() {
MyClass myClass = MyClass();
myClass = MyClass.named(42);
}
```

As such, the snippet from "problem" example could become:

```dart
class Concrete {
Concrete.foo(Widget callback(BuildContext c, T value))
: this._((c) => callback(c, doSomething(c));

Concrete.bar(Widget callback(BuildContext c, T value, T2 value))
: this._((c) => callback(c, doSomething(c), doSomethingElse(c));

Concrete._(this.callback);

final Widget Function(BuildContext context) callback;
}
```

This improves auto-complete and reduce pointless duplicates.

[provider]: https://github.com/rrousselGit/provider
[Consumer]: https://pub.dev/documentation/provider/latest/provider/Consumer-class.html
[Consumer2]: https://pub.dev/documentation/provider/latest/provider/Consumer2-class.html
[Selector]: https://pub.dev/documentation/provider/latest/provider/Selector-class.html
[ProxyProvider]: https://pub.dev/documentation/provider/latest/provider/ProxyProvider-class.html
[ProxyProvider2]: https://pub.dev/documentation/provider/latest/provider/ProxyProvider2-class.html

Contributor guide

Open the contributing guide

Research direction

Start with the proposal in this issue and compare it with the broader version in #276. Review the Consumer, Consumer2, Selector, ProxyProvider, and ProxyProvider2 examples to understand the duplicate APIs being discussed. Done means reaching and documenting a language-design decision about generic named constructors.

Written by the indexing model from the issue text.

Assessment

Tech stack
dart
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.