DWand
DWand

Reputation: 672

Is it possible to use a constructor function as a type of an argument of another function in TypeScript?

A few days ago I've found a TypeScript language. According to video reviews it looks pretty promising for me as it brings to JavaScript an appropriate code completion, implicit code documentation and, probably, makes it more type safety.

I'm trying to rewrite a simple AngularJS application in TypeScript. I'd like to specify types of parameters, which are injected to controllers. Let's assume the following JS code:

// service.js
angular.module('app').service('MyService', MyService);
function MyService() {
    this.test = function test() { console.log('test'); };
}

// controller.js
angular.module('app').controller('MyController', MyController);
function MyController($scope, MyService) {
    $scope.test = function test() { MyService.test(); };
}

I'm trying to achieve something like this:

// controller.ts
angular.module('app').controller('MyController', MyController);
function MyController($scope, MyService:MyService) {
    // ...
}

So it'd be easier to write code of the controller with code completion for MyService parameter. However, this code makes a compiler to emit error TS2304: Cannot find name 'MyService'.

I've tried a couple to things and found at least 2 possible solutions. However, non of them seems to be ideal.

1) Creation of an additional interface, which declares all methods of the service. But this approach requires a lot of additional typing (actually, we define the same set of methods with full signature twice and also have to update several things in case of changes). This way is totally okay when the interface is implemented multiple times, but looks redundant for a single AngularJS service.

2) Constructor function can be replaced with a class. This way it is possible to use a name of the class as a type of the parameter. However, this also leads to a couple of problems:

So, are there any other ways to pass a constructor function as a type of a parameter of another function? Thanks.

P.S.: I don't know whether it's necessary or not, but I'm using Sublime Text 3 with an official TypeScipt plugin and gulp-typescript for compilation.

Upvotes: 0

Views: 92

Answers (1)

rwisch45
rwisch45

Reputation: 3702

Yes, you can do this. See working CodePen

class MyController
{
  static $inject = ['MyService','$scope'];

  constructor(private myService:MyService, private $scope:any){
    this.$scope.test = this.myService.test;
  }  
}

class MyService{  
  test(){ 
    console.log('test');
  }
}

Upvotes: 1

Related Questions