Propagating type parameter from generic function's argument to the function call
While an object with a generic parameter preserves that type value, it is difficult to call a function passing/propagating that generic parameter. A work around is the call the function from the object. This seems quite tedious, surely there is, or can be a better way?
typedef GenericFunction<R, A> = R Function<G>(A args);
// in AppSetting class
R callTyped<R, A>(GenericFunction<R, A> fn, A args) => fn<T>(args);
void onSetting<T>(AppSetting<T> setting) {
print(T);
print(setting.runtimeType);
}
void main() {
test('test', () {
for (final setting in AppSetting.values) {
onSetting(setting); // prints dynamic, AppSetting<double>
setting.callTyped<void, AppSetting>(<G>(args) => onSetting<G>(setting as AppSetting<G>), setting); // prints double, AppSetting<double>
}
});
}
Sound like what you want is to extract the type variable from an AppSetting object.
There is no way to do that without the cooperation of the AppSetting class.
Type variables are not accessible outside of their lexical scope, meaning outside of the class that declared them.
If the AppSetting class had a method like
R callWith<R>(R Function<T>(AppSetting<T>) callback){
return callback<T>(this);
}
then you could use that to get access to the actual type argument that was passed to the AppSetting constructor.
The other alternative that has been suggested, is to allow destructuring to extract type variables, fx like:
AppSetting<final T> appSetting = someAppSetting;
which would extract the actual type argument of AppSetting that someAppSetting implements.
Sound like what you want is to extract the type variable from an
AppSettingobject.There is no way to do that without the cooperation of the
AppSettingclass. Type variables are not accessible outside of their lexical scope, meaning outside of the class that declared them.If the
AppSettingclass had a method likeR callWith<R>(R Function<T>(AppSetting<T>) callback){ return callback<T>(this); }then you could use that to get access to the actual type argument that was passed to the
AppSettingconstructor.The other alternative that has been suggested, is to allow destructuring to extract type variables, fx like:
AppSetting<final T> appSetting = someAppSetting;which would extract the actual type argument of
AppSettingthatsomeAppSettingimplements.
Ah, yes a simple callback providing access to the type parameter would be sufficient. There's no need to handle arguments, as the initial context can directly pass arguments to the body of the anonymous function.
return setting.callWith<SettingMenu<T>>(<G>() => SettingMenu<G>(setting: setting as Setting<G>, settingsController: settingsController) as SettingMenu<T>);