如果TypeScript是JavaScript的超集,为什么需要编写声明才能使用JavaScript库?

时间:2015-07-26 16:20:24

标签: javascript typescript

正如我所看到的,由TypeScript开发人员编写的examples,他们使用某种存根来实现与JavaScript的互操作性:

declare module Backbone {
    export class Model {
        constructor (attr? , opts? );
        get(name: string): any;
        set(name: string, val: any): void;
        set(obj: any): void;
        save(attr? , opts? ): void;
        destroy(): void;
        bind(ev: string, f: Function, ctx?: any): void;
        toJSON(): any;
    }
    ...
}
interface JQuery {
    fadeIn(): JQuery;
    fadeOut(): JQuery;
    focus(): JQuery;
    html(): string;
    html(val: string): JQuery;
    show(): JQuery;
    addClass(className: string): JQuery;
    removeClass(className: string): JQuery;
    append(el: HTMLElement): JQuery;
    val(): string;
    val(value: string): JQuery;
    attr(attrName: string): string;
}

这看起来很奇怪。我可以省略编写这样的存根,只需使用jQuery对象并调用它的方法吗?我希望,这是可能的,因为TypeScript是JavaScript的超集,如果它可以在JavaScript中使用,那么它也可能在TypeScript中成为可能。从TypeScript中调用JavaScript代码的最佳方法是什么?

3 个答案:

答案 0 :(得分:2)

它们不是存根,它们是类型声明。由于javascript是无类型的,因此需要将类型添加到函数和方法签名中。如果没有这些打字稿,则无法帮助您进行任何静态分析。

例如:

confirm函数打开一个弹出窗口,询问您一个问题,并根据您是否点击'ok'或'cancel'获得布尔值true或false。在普通的旧Javascript中,您可以像这样调用函数:

var x = prompt(1 + 1) + "hello world";

这没有意义,因为prompt需要一个字符串参数并返回一个布尔值。 Typescript通过在标准的lib.d.ts中添加此声明来帮助:

declare function confirm(message?: string): boolean;

因此,我上面编写的代码会使用typescript编译器导致编译错误。

答案 1 :(得分:1)

您可以完全省略这些声明并生成有效的Typescript代码;这些说明的目的是添加有关vanilla Javascript API的返回类型的信息,以便从Typescript的静态类型检查中受益。如果您不使用它们,那么从普通JS库导入的所有内容都将返回类型为any的值,而Typescript无法对其进行检查。

这种做法被称为type declaration files,您可能不需要自己编写:最流行的Javascript库可以在线获得数百个这样的声明文件。

答案 2 :(得分:1)

TypeScript会阻止您使用不存在的变量。例如,如果我只在.ts文件中包含此代码:

$("#myElement").hide();

TypeScript会将其输出到.js文件中;但是,它也会抛出一个编译错误,告诉我$还没有被定义。这是为了防止我犯错误。

因此,当我使用JavaScript库(如jQuery)时,如果没有首先告诉编译器有关JS代码中的变量(例如$),编译器会抛出一个错误告诉我他们并非如此。定义。这实际上可能是我的错误...编译器不知道,因为我还没有告诉它,它无法正确分析JavaScript代码以找出答案。

为了解决这个问题,我可以继续告诉编译器 至少 定义带有any的环境定义时,这不是错误类型:

declare var $: any;

现在我的.ts文件中出现了错误,因为我已经告诉编译器这个变量存在于TypeScript代码之外并且使用any定义它类型,我告诉它这个变量可以以任何方式使用(这是该语言的可选静态类型部分)。

但是,没有关于变量的类型信息不是优选的。它使用起来很容易,因为对变量的使用没有任何限制。为了解决这个问题,我可以继续描述一下$的类型,但是这个类型定义已经存在,所以我可以使用tsd将它安装到我的应用程序中:

tsd install jquery

然后在我的应用程序中使用下载的jquery.d.ts文件。

相关问题