Brett Postin
Brett Postin

Reputation: 11375

RequireJS module declarations in TypeScript

I've recently updated to TypeScript 0.9.5 which is now throwing up new errors during compilation.

I'm defining an AMD module using RequireJS as outlined HERE.

define('myModule', [
    'angular',
    'config'
    ], function (angular, config) {
        'use strict';

        ...
});

The TypeScript definition file for RequireJS has the following definition for RequireDefine:

/**
* Define a module with a name and dependencies.
* @param name The name of the module.
* @param deps List of dependencies module IDs.
* @param ready Callback function when the dependencies are loaded.
*   callback deps module dependencies
*   callback return module definition
**/
(name: string, deps: string[], ready: (...deps: any[]) => any): void;

However I'm getting the following errors:

error TS2082: Build: Supplied parameters do not match any signature of call target:
error TS2087: Build: Could not select overload for 'call' expression.

The intellisense error states:

Call signatures of types '(angular:any, config:any) => any' and '(...deps: any[]) => any' are incompatible.

Is the definition file incorrect? Where am I going wrong with the callback parameters?

Further Information:

Changing the declaration to the following now compiles.

define('myModule', [
    'angular',
    'config'
    ], function (...args:any[]) {
        'use strict';

        ...
});

However moving to a single parameter object is surely a backwards step? Is this a limitation of the definition file or the TypeScript compiler?

Upvotes: 4

Views: 1098

Answers (2)

basarat
basarat

Reputation: 276181

For function definitions that take anything and return anything the new recommended syntax is :

function require(fn: Function){

}

Upvotes: 1

Benjamin Gruenbaum
Benjamin Gruenbaum

Reputation: 276266

Is this a limitation of the definition file or the TypeScript compiler?

It's both. It's a "limitation" of the TypeScript compiler (limitation is quoted since it is enforcing a valid constraint here), and can be fixed from the definition file.

It's actually a lot simpler to reproduce this case:

function argLoving(fn: (...deps: any[]) => any){

}

argLoving(function(x,y){ // <- compile error

});

The issue is - while you can call the function in argLoving with x and y when you declare or supply it - it has to actually accept varargs to not break type safety.

Imagine the following:

function argLoving(fn: (...deps: any[]) => any){

}
function foo(x:any,y:any){

}
argLoving(foo);

Now it's clear that argLoving is accepting a function that works on a variable number of arguments but foo only works on exactly two.

That's the type problem.

The way C# solves this is pretty ugly* (with Func for example), so if you're looking for a quick& dirty fix - what you can do is just define multiple signatures in your .d.ts file:

This of course compiles with no problem:

function argLoving(fn: (x:any) => any)
function argLoving(fn: (x:any,y:any) => any)
function argLoving(fn: (x:any,y:any,z:any) => any)
function argLoving(fn: (x:any,y:any,z:any,a:any) => any)
function argLoving(fn: (...deps: any[]) => any){

}
function foo(x:any,y:any){

}
argLoving(foo); // this compiles now

* http://msdn.microsoft.com/en-us/library/bb534960(v=vs.110).aspx - look at all the Action and Func overloads in the left


Update:

After I opened an issue on GitHub - the author of DefinitelyTyped put pull request and for this issue using the same fix suggested here https://github.com/borisyankov/DefinitelyTyped/issues/1434 . It's being discussed here https://github.com/borisyankov/DefinitelyTyped/pull/1435

Upvotes: 4

Related Questions