Output event in two-way binding (of type dynamic) is not assignable to component input (of type String)

String get title => post.title;
In contrary to #523 this one is not related to | async
I do find it curious how it complains about the output type, not the input type. This implies that the logic (whatever I'm doing) thinks that String is assignable to dynamic, and not vice-versa.
I may have put in a check that the two must be equal -- it seems like a truism that if type A is assignable to B, and B is assignable to A, that they must be equal. However, as shown in this case, that's not true in Dart.
I got the same error and lots of similar ones all over my project.
Some more examples:
warning: Attribute value expression (of type dynamic) is not assignable to component input (of type TemplateRef) when using code similar to:
<template #picker>
<datepicker></datepicker>
</template>
<template [ngTemplateOutlet]="picker"></template>
And also warning: A value of type 'dynamic' can't be assigned to a variable of type 'RateGroup'. when using the ngModelChange event directly like:
<input ... (ngModelChange)="entity.rateGroup=$event">
So it seems that TemplateRefs and ngModelChange Events use dynamic as type. That would mean the errors are all correct, its just that either the angular code generator needs to annotate them with better types or this plugin needs to infer more information.

So should we consider this a false positive that's going to be cleaned up eventually or do we need to always have our binding variables be dynamic in the sister Dart file? Apparently ngForm only traffics in dynamics so when it tries to set the value it can't handle any typed variable.
Here currentParentGatewayId is an int in the Dart file.
Do we need to implement patterns like this (seems ugly)?
dynamic get forBinding => myRealInt;
set forBinding(dynamic value) => myRealInt = value as int;
int myRealInt = 0;
Wondering what the best practice is going to be here.
I still have not been able to repro this. This is definitely not intended behavior.
Apologies on how long this has been opened. I've been working on Dart 2 lately.
I was not able to repro this even with fuzz testing, but I think it has something to do with the switch to making the analyzer use strong mode.
Could it have something to do with using implicit-dynamic: false in our analysis options?
Ah, no, but, disabling implicit downcasts absolutely would! Have you done that as well by any chance?
If so then I think it would be working as intended for this case.
Unless ngModel carries more type information than the plugin is recognizing....I think I may be able to come up with a more precise type of I try to track type validators, but that might be undecidable in general.
I'll also talk to the angular team about their thoughts for this...
Lack of a good workaround is an issue as well.
If you do indeed have implicit downcasts disabled, that is.
On Sun, Aug 12, 2018, 3:47 PM Rob Bishop [email protected] wrote:
Could it have something to do with using implicit-dynamic: false in our analysis options?
— You are receiving this because you were assigned. Reply to this email directly, view it on GitHub https://github.com/dart-lang/angular_analyzer_plugin/issues/524#issuecomment-412377178, or mute the thread https://github.com/notifications/unsubscribe-auth/ABjWe8lOOb5zrigDsp9-YZZYnwa1tyWaks5uQLCHgaJpZM4S2sV6 .
Yes I have implicit casts set to false as well.
Yeah, so that's the root of the problem. To quote myself:
I may have put in a check that the two must be equal -- it seems like a truism that if type A is assignable to B, and B is assignable to A, that they must be equal. However, as shown in this case, that's not true in Dart.
That's not true in Dart when you have implicit downcasts enabled.
dynamic x;
int y;
x = y; // always valid
y = x; // only valid with implicit-downcasts: true
here x would be ngModel, because in the definition of it, ngModelChange returns a Stream, so, Stream<dynamic>, which means $event (which correlates here to x), is dynamic. https://github.com/dart-lang/angular/blob/67d1bd06a152956e315d443042ef9da646e57552/angular_forms/lib/src/directives/ng_model.dart#L111
@leonsenft @matanlurey will be interested.
The solution to this in which the plugin tracks angular's ValueAccessor DI, which would enable us to implement checks for for instance #233. I had thought heavily on this before at some point, but I don't remember getting much clear idea of what an implementation would look like and what its limitations would be (in general, angular DI would be NP-hard to analyze without just running it).
I have about 120 of these warnings in my project currently. I don't want to go about adding a hacky workaround for each unless it's unavoidable/best practice.
Is there a way, or could a way be added, to suppress warnings of specific types coming from the plugin before a solution is in place?
You could add this to each template (top line):
<!-- @ngIgnoreWarnings: invalid_assignment -->
but you probably don't want that.
I'll see if I can't loosen this based on the fact that I hope to track the type of NgModel. But still, I'm wary because its doing exactly what its supposed to do.
It may be better to, for instance, make a directive that extends NgModel that has a type [ngModelInt]="foo", and then you wouldn't have to wrap every two-way-bound value in a casting getter/setter.
Could the Angular team provide ngModelWhatever for all basic types and make them available alongside ngModel?
Rather than have people recreating these over and over?
I wouldn't mind using [(ngModelString)] for example over [(ngModel)]. Provides a nice clue during template development as to what types are involved.
I couldn't get <!-- @ngIgnoreWarnings: invalid_assignment --> to work.
Still seeing much flakiness wrt updating too.
@MichaelRFairhurst it would be great if you could let us know which approach you're going to take as soon as you know it. If, for example, the only way to solve this, is by adding ngModelInt etc... directives, then we could already start to migrate our codebase with our custom directives.
These ~100 warnings in my project are haunting me in my dreams! :)
Is there any update on this? Still having these warnings and it's really annoying and hides other important warnings and hints.
@MichaelRFairhurst from what I can see, the new directiveTypes doesn't help either, right?