How to use underscore lib from DefinitelyTyped with typescript?
Asked Answered
L

5

12

DefinitelyTyped has provided a underscore declaration file, which defines a List interface, and used it heavily in the code.

// Common interface between Arrays and jQuery objects
interface List {
    [index: number]: any;
    length: number;
}

interface UnderscoreStatic {
    sortBy(list: List, iterator?: any, context?: any): any;
    groupBy(list: List, iterator: any): any;
    countBy(list: List, iterator: any): any;
}

I'm trying to use the countBy function:

// <reference path="../DefinitelyTyped/underscore/underscore.d.ts" />

declare var _: UnderscoreStatic;

_.countBy([1,2,3], function(item) {
    return item%2;
});

When I compile the file, it throws error:

> tsc commons.ts

> E:/commons.ts(5,0): Supplied parameters do not match any signature of call target:
    Could not apply type 'List' to argument 1, which is of type 'number[]'

I don't know why this error happened, since number[] fit the interface List.

Where is wrong, and how to fix it?

Leelah answered 29/1, 2013 at 14:33 Comment(1)
2016 update: import * as _ from "underscore";Gleanings
P
6

You need to pass an object compatible with the List interface, which is an array with a length:

/// <reference path="underscore.d.ts" />

var list: List;
list[0] = 1;
list[1] = 2;
list[2] = 3;
list.length = 3;

_.countBy(list, function (item) {
    return item % 2;
});

In all honesty, an array technically fulfils this as it has a length property - but the above code compiles.

The shorthand version of this is a bit nasty:

/// <reference path="underscore.d.ts" />

var list = <List><any> [1, 2, 3];

_.countBy(list, function (item) {
    return item % 2;
});
Pediatrics answered 29/1, 2013 at 14:37 Comment(5)
I can't image I have to add a length to an array each time I use it, just in order to make it compile.Leelah
Couldn't you also just cast the array: _.countBy((<List>[1,2,3]) ... etc. ? (Don't have the underscore lib to hand so can't test this).Baccalaureate
You get "Cannot convert number[] to List". One alternative would be to accept that number[] would be a better typing in underscore.d.ts as we know it will have an indexer and a length. You could get away with the really hideous: var list: List = <List><any> [1, 2, 3];Pediatrics
@Leelah I have added a short-hand version that is a bit nasty, but means you don't have to use the expanded version. Bear in mind this could well be a mistake in the .d.ts definition - a regular underscore user might be able to confirm, in which case I'm happy to submit an update.Pediatrics
Update - I have submitted a pull request on Definitely Typed to remove the List interface in favour of using the any[] type, which will allow normal use of underscore.Pediatrics
S
2

Update 2021

Add the following dependencies to package.json:

  "dependencies": {
    "underscore": "^1.13.4"
  },
  "devDependencies": {
    "@types/underscore": "^1.11.4"
  }

Then run:

$ npm install

In your TypeScript files, import underscore using:

import * as _ from 'underscore';
Sorensen answered 30/9, 2021 at 15:46 Comment(0)
S
1

Using Typescript 2.0, you can import underscore with the import statement like below:

import * as _ from "underscore";

Then, call any underscore function using _.<function_name>.

PS: don't forget to install underscore library with npm for example.

Saragossa answered 23/1, 2017 at 16:55 Comment(0)
C
0

Check that the underscore TypeScript definition file matches the version of underscore you're using. The signature of countBy has changed and if the TS definition didn't match the underlying JS you'd get some unexpected behaviour.

Colum answered 18/2, 2016 at 11:4 Comment(0)
I
0

First add underscore typing:

npm install typings --global
typings install dt~jasmine --save --global

Then reference this file in your .ts source

/// <reference path="../../../typings/underscore.d.ts" />

Then import underscore to avoid compilation errors (be careful - underscore lib in this case should be installed as npm reference, not bower: npm install underscore --save)

import _ = require('underscore');

Then use underscore as usual using "_" global variable

_.isNumber(123);
Isooctane answered 12/10, 2016 at 15:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.