Skip to content
This repository has been archived by the owner on Sep 16, 2022. It is now read-only.

Commit

Permalink
feat(Meta): Add castCallback[1,2]ForDirective.
Browse files Browse the repository at this point in the history
Closes #1489.

PiperOrigin-RevId: 204490128
  • Loading branch information
matanlurey committed Jul 13, 2018
1 parent c0e75c0 commit c19c944
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 0 deletions.
8 changes: 8 additions & 0 deletions angular/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
</div>
```

* Added `package:angular/meta.dart`, a series of utilities for additional
static analysis checks and/or functions to retain semantics for migration
purposes, starting with `castCallback1ForDirective` and
`castCallback2ForDirective`. These methods are _only_ intended to be used
as stop-gaps for the lack of generic support in AngularDart directives and
components. Closes [#1489][].

## Bug fixes

* Fails the build immediately if an element in a component's `pipes` list is
Expand Down Expand Up @@ -53,6 +60,7 @@
[#1295]: https://github.com/dart-lang/angular/issues/1295
[#1455]: https://github.com/dart-lang/angular/issues/1455
[#1484]: https://github.com/dart-lang/angular/issues/1484
[#1849]: https://github.com/dart-lang/angular/issues/1489

## 5.0.0-beta

Expand Down
62 changes: 62 additions & 0 deletions angular/lib/meta.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/// Utilities and metadata annotations for static analysis purposes.
@experimental
library angular.meta;

// This line is to force that `package:angular/meta.dart` is not used in the VM.
//
// ignore: unused_import
import 'dart:html';

import 'package:meta/meta.dart';

/// Wraps a typed [callback] with a single parameter of type [A].
///
/// This function returns an _untyped_ callback with a single parameter
/// of type `dynamic`, which in turn dynamically is casted/checked to
/// [A] before invoking [callback].
///
/// Common usage is when creating a callback to pass to a `@Component`
/// that is expecting generic type parameters, but is missing them due
/// to missing support in Angulardart:
/// ```dart
/// typedef ItemRenderer<T> = String Function(T);
///
/// abstract class Dog {
/// String get name;
/// }
///
/// @Component(
/// selector: 'my-component',
/// directives: [ItemListComponent],
/// )
/// class MyComponent {
/// final itemRenderer = castCallback1((Dog dog) => dog.name);
/// }
///
/// class ItemListComponent<T> {
/// @Input()
/// ItemRenderer<T> itemRenderer;
/// }
/// ```
///
/// **NOTE**: This method is _only_ intended as a workaround for the lack-of
/// reified generics for components and directives. Do **not** use as a general
/// purpose workaround: https://github.com/dart-lang/angular/issues/68
T Function(dynamic) castCallback1ForDirective<T, A>(
T Function(A) callback,
) {
return (element) => callback(element as A);
}

/// Wraps a typed [callback] with two parameters of types [A] and [B].
///
/// See [castCallback2ForDirective] for details.
///
/// **NOTE**: This method is _only_ intended as a workaround for the lack-of
/// reified generics for components and directives. Do **not** use as a general
/// purpose workaround: https://github.com/dart-lang/angular/issues/68
T Function(dynamic, dynamic) castCallback2ForDirective<T, A, B>(
T Function(A, B) callback,
) {
return (a, b) => callback(a as A, b as B);
}

0 comments on commit c19c944

Please sign in to comment.