angular
angular copied to clipboard
Pipes and generics
Hi. I have pipe for connecting data from redux store:
import 'package:angular/angular.dart';
import 'package:redux/redux.dart';
typedef Selector<K> = dynamic Function(K state);
@Pipe('stateRef', pure: false)
class ConnectPipe<K> extends PipeTransform {
final Store<K> _store;
final ChangeDetectorRef _detector;
final NgZone _zone;
ConnectPipe(this._store, this._detector, this._zone) {
_store.onChange.listen((K _) => marker());
}
Selector<K> _selector;
dynamic _innerState;
dynamic transform(Selector<K> selector) {
_selector = selector;
return _innerState = selector(_store.state);
}
void marker() {
final dynamic some = _selector(_store.state);
if (some != _innerState) {
_zone.run(_detector.markForCheck);
}
}
}
When I try use it with template
<simple
[a]="numConverter | stateRef">
</simple>
UsersConverter - selector
int numConverter(SimpleState state) => 42;
When compile it I've got error:
[error] The argument type '(SimpleState) → int' can't be assigned to the parameter type '(dynamic) → dynamic'.
As I can see angular template cannot infer K as generic - SimpleState and treat this as dynamic. And I have type mismatch. How to workaround it or how to add generic types to pipes as I can for directiveTypes.
@leonsenft @matanlurey @alorenzen ?
Sorry for the late reply. There's no support in the framework for instantiating pipes with generics yet.
I can think of two potential workarounds.
- Specify type arguments using inheritance. This might be the best option if you're going to need few types.
// No pipe annotation.
abstract class ConnectPipe<K> extends PipeTransform {
... // unchanged.
}
@Pipe('intStateRef', pure: false)
class IntConnectPipe extends ConnectPipe<int> {
IntConnectPipe(...) : super(...);
}
- Only pass functions with dynamic parameters to your pipe. If you want, you can add an assert or type check inside the function to retain some type safety.
int numConverter(dynamic state) {
if (state is SimpleState) {
...
}
}