如何在TypeScript中使用来自DefinitelyTyped的Underscore库?

12

DefinitelyTyped 提供了 underscore 的声明文件,其中定义了一个 List 接口,并在代码中广泛使用。

// 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;
}

我试图使用countBy函数:

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

declare var _: UnderscoreStatic;

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

当我编译文件时,它会抛出错误:

> 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[]'

我不知道为什么会出现这个错误,因为number[]符合接口List的要求。

有哪里做错了,怎样才能修复它呢?


3
2016年更新: import * as _ from "underscore"; 可翻译为:使用“underscore”模块时,可以通过 import * as _ from "underscore"; 的方式进行导入。 - David
5个回答

6

您需要传递一个与List接口兼容的对象,它是一个具有长度的数组:

/// <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;
});

说实话,数组在技术上实现了这一点,因为它有一个长度属性-但是以上代码可以编译。

简写版本有点难看:

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

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

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

我无法想象每次使用数组时都必须添加一个“长度”才能使其编译。 - Freewind
你也可以直接将数组转换为列表,如 _.countBy((<List>[1,2,3]) ... 等等。 (我手头没有 underscore 库,无法测试) - Jude Fisher
你会得到“无法将number[]转换为List”的错误。一个替代方案是在underscore.d.ts中接受number[]作为更好的类型,因为我们知道它将具有索引器和长度属性。你可以使用非常丑陋的方式来解决这个问题:var list: List = <List><any> [1, 2, 3]; - Fenton
@Freewind 我添加了一个有点不好的简写版本,但这意味着您不必使用扩展版本。请记住,这可能是 .d.ts 定义中的错误 - 一个常规下划线用户可能能够确认,如果是这样,我很乐意提交更新。 - Fenton
6
更新 - 我已经向 Definitely Typed 提交了一个拉取请求,以删除 List 接口并使用 any[] 类型代替,这将允许正常使用 Underscore。 - Fenton

2

更新2021

请在package.json中添加以下依赖项:

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

然后运行:

$ npm install

在你的TypeScript文件中,使用以下代码导入underscore:
import * as _ from 'underscore';

1

使用Typescript 2.0,您可以像下面这样使用import语句导入underscore:

import * as _ from "underscore";

然后,使用_.<function_name>调用任何下划线函数。

PS:不要忘记使用npm安装underscore库。


0

首先添加下划线类型:

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

然后在你的 .ts 源文件中引用这个文件

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

然后导入underscore以避免编译错误(注意 - 在这种情况下,underscore库应该作为npm引用安装,而不是bower:npm install underscore --save

import _ = require('underscore');

然后像往常一样使用下划线,使用全局变量"_"

_.isNumber(123);

0

请检查下划线 TypeScript 定义文件是否与您正在使用的下划线版本匹配。countBy 的签名已更改,如果 TS 定义与底层 JS 不匹配,则可能会出现一些意外行为。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接