Generated copyWith looses type information if nested in another class
Hi :) I have the following (very strange) issue as an extension to the environment in #24. Image the following class definition:
@immutable
@MappableClass()
class SingleSetting<T> with Mappable {
final List<T>? properties;
const SingleSetting({
this.properties,
});
}
@immutable
@MappableClass()
class Settings with Mappable {
final Map<String, SingleSetting>? settings;
const Settings({
this.settings,
});
}
If I initiate something like
SingleSetting setting = SingleSetting<String>();
the condition
setting.copyWith(properties: ['test']).runtimeType == SingleSetting<String>
is true.
If I prepare the following class
Settings settings = Settings<String>;
settings = settings.copyWith(settings: {'Test': const SingleSetting<String>(properties: ['test'])});
SingleSetting setting = settings.settings['Test'];
the condition
setting.runtimeType == SingleSetting<String>
is true as expected.
However the condition
setting.copyWith(properties: ['test']).runtimeType == SingleSetting<String>
is false but
setting.copyWith(properties: ['test']).runtimeType == SingleSetting<dynamic>
is true.
The behavior is very strange and for now, I can't explain it. Do you have any ideas, about what the issue can be? Thank you!
Ok makes sense. Its because for this class the copyWith is still an extension and not a mixin, which causes the type parameter to get lost. So I just change it to mixins everywhere.
Ok, good, that it somehow makes sense. I was already worried to write a complete stupid GIT issue :D
If you are interested why this is: Extensions work with the static type of an object, while mixins work with the runtime type.
So having an extension on A<T>, then for A<dynamic> a = A<int>() the extension would only get T = dynamic while the same as a mixin would have the correct type T = int.
I just didn't realize this before.
Thanks for the explanation! I wasn't aware of that, as well.
Published in next prerelease
Hi :) Unfortunately, the issue still exists in dev.5. Now with:
@immutable
@MappableClass()
class SingleSetting<T> with SingleSettingMappable<T> {
final List<T>? properties;
const SingleSetting({
this.properties,
});
}
@immutable
@MappableClass()
class Settings with SettingsMappable {
final Map<String, SingleSetting>? settings;
const Settings({
this.settings,
});
}
Do you have some reproduction code?
@nblum37 any updates?
I am unfortunately currently finishing our next release. I hope I will be able to provide the reproduction code next week.
I will close this now. If the issue persists in the newest version (2.0.0-dev.8) please reopen.
I will check it with the new dev version :)