AngularJS Filter with TypeScript and injection AngularJS Filter with TypeScript and injection typescript typescript

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]

You can find my project here, and a sample of filter here