angular icon indicating copy to clipboard operation
angular copied to clipboard

Type inference for MultiToken in Angular Dart

Open szepeshazi opened this issue 5 years ago • 1 comments

Using Dart 2.5.0, Angular 5.3.

Given the following component:

const MultiToken<String> stringsToken = MultiToken("stringListToken");

@Component(
  selector: 'my-app',
  template: '<div>{{ myStringValues.join(", ") }}</div>',
  providers: [
    ValueProvider.forToken(stringsToken, "one"),
    ValueProvider.forToken(stringsToken, "two"),
  ]
)
class AppComponent {

  final List<String> myStringValues;

  AppComponent(@Self() @Inject(stringsToken) this.myStringValues);
}

I'm getting the exception

dart_sdk.js:101871 EXCEPTION: Type 'List<dynamic>' should be 'List<String>' to implement 
expected type 'List<String>'

This happens when the constructor tries to inject the provided List value to the local myStringValues, as if the provisioned List was downcasted to List<dynamic>. Now, if I replace the token creation with

const MultiToken<String> stringsToken = MultiToken<String>("stringListToken");

the component will work as expected, the injected values will be displayed.

How come that, using the first declaration syntax, the type of the MultiToken could not be inferred to String? To add to my confusion, if using the first version of declaration, i.e.

const MultiToken<String> stringsToken = MultiToken("stringListToken");

and then printing the runtimeType of stringsToken, it will print MultiToken<String>.

So where, and how, the bound generic type, is lost in the first case, when trying to inject the value?

szepeshazi avatar Sep 19 '19 14:09 szepeshazi

Thanks for filing, it's possible this is a bug in the analyzer, or in how we're using it to extract the constant value. We'll have to look into it further; in the meanwhile I'd suggest just typing the right hand side:

const stringsToken = MultiToken<String>('stringListToken');

leonsenft avatar Sep 25 '19 22:09 leonsenft