Skip to content

Type parameter is lost when using a typedef for a mixin #49208

@navaronbracke

Description

@navaronbracke

I have a mixin that uses some generics.
Since the effective type name of the mixin got quite long in the usage of said mixin, I put it in a typedef.
When I then consumed a method from the mixin, I noticed that a generic type came out as dynamic, even though the effective type was specified in the generic type bound in the with clause / typedef.

Strangely enough, when not using a typedef and just using the mixin type directly the type was correctly inferred and I had no dynamic anymore.

Steps to reproduce

  1. dart create myapp (a console app is fine)
  2. add the files from the code sample under the /lib folder
  3. hover over the method in case 1, works as expected (typing is inferred correctly)
  4. replace case 1 with case 2
  5. hover over the method again
  6. the IDE tooltip displays dynamic even though the type that was specified in the typedef should have been inferred
Code sample

my_mixin.dart

import 'package:myapp/my_model.dart';
import 'package:myapp/widgets.dart';

mixin MyMixin<T, W extends StatefulWidget> on State<W> {
  void listenToEvents(Stream<MyModel<T>> stream) {
    stream.listen((event) {});
  }
}

my_model.dart

class MyModel<T> {
  MyModel(this.data);

  final T data;
}

my_widget.dart

import 'package:myapp/my_mixin.dart';
import 'package:myapp/my_model.dart';
import 'package:myapp/widgets.dart';

typedef MyMixinTypedef = MyMixin<String, MyWidget>;

class MyWidget extends StatefulWidget {}

// TODO: hover over `listenToEvents` and observe the tooltip

// Case 1: without additional typedef
// produces `void listenToEvents(Stream<MyModel<String>> stream)`

class MyWidgetState extends State<MyWidget> with MyMixin<String, MyWidget> {
  void doSomething() {
    listenToEvents(Stream.value(MyModel('foo')));
  }
}


// Case 2: with typedef for the mixin
// produces `void listenToEvents(Stream<MyModel<dynamic>> stream)`

/*
class MyWidgetState extends State<MyWidget> with MyMixinTypedef {
  void doSomething() {
    listenToEvents(Stream.value(MyModel('foo')));
  }
}*/

widgets.dart

abstract class Widget {}

abstract class StatefulWidget extends Widget {}

abstract class State<T extends StatefulWidget> {}

Dart SDK version: 2.17.1 (stable) (Tue May 17 17:58:21 2022 +0000) on "macos_x64"
Dart Code version: v3.42.1
VSCode version: 1.67.2 (Universal)

Metadata

Metadata

Assignees

Labels

P2A bug or feature request we're likely to work onlegacy-area-analyzerUse area-devexp instead.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions