This is what worked for me:
In a separate file, I declare module app :
// IRootScopeService.d.ts declare module app { interface IRootScopeService extends ng.IRootScopeService { // $state: ng.ui.IState // previousState: any; currentState: any; } }
I called it IRootScopeService.d.ts , because these are declaration files that work with the declare keyword. To make it modular, this file will be available only for access to the interface using app.IRootScopeService .
Now, in the controller file, it's like a controller function:
//CoreCtrl-ctrl.ts ... function CoreCtrl( $state: angular.ui.IState, $rootScope: app.IRootScopeService ) { var vm = this; $rootScope.previousState = undefined; $rootScope.currentState = undefined; $rootScope.$on('$stateChangeSuccess', function(ev, to, toParams, from, fromParams) { $rootScope.previousState = from.name; $rootScope.currentState = to.name; }) // $rootScope.previousState = undefined; // $rootScope.currentState = undefined; } ...
Check out the app.IRootScopeService , which gives us a type for $rootScope . Now $rootScope.currentState and $rootScope.previousState will not $rootScope.previousState error in typescript .
PART 2
We can add more interfaces to the app module in the new IScope.d.ts file just to keep it modular:
// IScope.d.ts declare module app { interface IScope extends ng.IScope { // $root: IRootScopeService; // greet:string; name:string; address:string; } }
Now we have two personalized / customizable interfaces app.IRootScopeService and app.IState , where we can continue to add new properties that we would like to add to $rootScope and $scope .
Please note that we are not prefixed with ng. at $root: IRootScopeService; because we are accessing the app.IRootScopeService from inside the module app .
Hope this helps. Good luck.