AngularJS Filter with TypeScript and injection
It's generally better to use a function
+module
instead of a class
when writing an Angular filter. You can structure the code like this:
function FriendlyDateFilter($filter) { return function (s: string): string { /* Your logic here */ } /* Helper logic here */}module FriendlyDateFilter { export var $inject = ['$filter'];}angular.module("ReadingLog").filter("FriendlyDateFilter", FriendlyDateFilter);
You could also place both FriendlyDateFilter
declarations inside another module
if you're trying to avoid adding too much to the global scope.
First, you need to use angular.d.ts
definition file.
Then, you simply do the following :
MyFilter.$inject = ["$log"];function MyFilter ($log: ng.ILogService): Function { return function(msg: string) { $log.log("I'm injected!"); return msg; };}angular.module("testModule").filter("MyFilter", MyFilter);
$inject
property is available in Function
thanks to these lines in angular.d.ts
:
// Support for painless dependency injectioninterface Function { $inject?: string[];}
See https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/angularjs/angular.d.ts#L12
I had the same problem while writing my own DI system for AngularJs 1.3 & Typescript. To solve this I wrote a decorator that accepts a class that implements the following interface:
interface IFilter { filter(value?: any, ...args): any;}
and it registers the filter with the following code:
var filterFactory = (...args) => { var filterObject = new target(...args); if (typeof filterObject.filter === 'function') { return filterObject.filter.bind(filterObject); } console.warn('Invalid filter: filter() method not found for:', filterName) return function() { }; //dummy filter, so it won't break everything };var constructorArray: Array<any> = injector.resolveParamNames(target); app.filter(filterName, constructorArray.concat(filterFactory));
My library uses a custom version of the TypeScript compiler, which is able to emit interface metadata that is used by injector.resolveParamNames
to build the classic constructor array like this one: ['$q', '$timeout', FilterFactory]