【问题标题】:Using jQuery plugin in TypeScript在 TypeScript 中使用 jQuery 插件
【发布时间】:2012-09-25 00:46:46
【问题描述】:

使用打字稿时,我需要为我使用的每个外部 js 导入一个 plugin.d.ts 吗? 换句话说,我需要创建一个包含所有接口的 jQuery.d.ts 吗?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    jQuery 插件(和其他基于插件的库)的问题在于,您不仅需要为基础库提供 library.d.ts 文件,而且还需要为每个插件提供一个 plugin.d.ts 文件。并且不知何故,这些 plugin.d.ts 文件需要扩展 library.d.ts 文件中定义的库接口。幸运的是,TypeScript 有一个漂亮的小功能可以让你做到这一点。

    对于classes,目前在项目中只能有一个类的单一圆锥定义。因此,如果您定义 class Foo,则您在 Foo 上添加的成员就是您所得到的。 Foo 的任何其他定义都将导致错误。但是,对于interfaces,成员是相加的,因此如果您使用一组成员定义interface Bar,您可以再次定义“界面栏”以将其他成员添加到interface。这是以强类型方式支持 jQuery 插件的关键。

    因此,要添加对给定 jQuery 插件的支持,您需要为要使用的插件创建一个 plugin.d.ts 文件。我们在项目中使用jQuery Templates,所以这是我们创建的 jquery.tmpl.d.ts 文件以添加对该插件的支持:

    interface JQuery
    {
        tmpl(data?:any,options?:any): JQuery;
        tmplItem(): JQueryTmplItem;
        template(name?:string): ()=>any;
    }
    
    interface JQueryStatic
    {
        tmpl(template:string,data?:any,options?:any): JQuery;
        tmpl(template:(data:any)=>string,data?:any,options?:any): JQuery;
        tmplItem(element:JQuery): JQueryTmplItem;
        tmplItem(element:HTMLElement): JQueryTmplItem;
        template(name:string,template:any): (data:any)=>string[];
        template(template:any): JQueryTemplateDelegate;
    }
    
    interface JQueryTemplateDelegate {
        (jQuery: JQueryStatic, data: any):string[];
    }
    
    interface JQueryTmplItem
    {
        data:any;
        nodes:HTMLElement[];
        key:number;
        parent:JQueryTmplItem;
    }
    

    我们做的第一件事就是定义添加到JQuery 接口的方法。这些让您在输入$('#foo').tmpl(); 时获得智能感知和类型检查接下来我们向JQueryStatic 接口添加方法,当您输入$.tmpl(); 时会显示这些方法最后jQuery Templates 插件定义了一些它自己的数据结构,所以我们需要为这些结构定义接口。

    现在我们已经定义了额外的接口,我们只需要从使用的 .ts 文件中引用它们。为此,我们只需将以下引用添加到 .ts 文件的顶部即可。对于该文件,TypeScript 将同时看到基本的 jQuery 方法和插件方法。如果您使用多个插件,请确保您引用了所有单独的 plugin.d.ts 文件,您应该会很好。

    /// <reference path="jquery.d.ts"/>
    /// <reference path="jquery.tmpl.d.ts" />
    

    【讨论】:

    • 这仍然是当前 TypeScript 版本(即 0.9.5)的方式吗?
    • 然而,这似乎不适用于纯 TypeScript 文件,例如myplugin.ts 当定义 interface JQuery {} 时,它会在该文件中将 JQuery 接口覆盖为空,从而导致很多错误。它确实适用于d.ts 文件。
    • 链接坏了:(
    • 如何使用流类型定义文件来完成?
    • interface JQueryFlowType extends JQuery { flowtype?: (options: any) =&gt; JQueryFlowType; } 。如果您不关心 IDE 支持,而只想实例化插件,请使用之前的定义。
    【解决方案2】:

    使用.d.ts 声明文件可能更好,但作为替代方案,您也可以使用TypeScript 的global augmentation and declaration merging 向JQuery 的接口添加方法。您可以在任何 TypeScript 文件中放置类似以下内容:

    declare global {
        interface JQuery {
            nameOfPluginMethod(arg: any): JQuery;
        }
    }
    

    【讨论】:

    • 这在常规 TS 文件中内联工作,非常适合扩充遗留代码而不会乱扔代码库的其余部分。非常感谢!
    【解决方案3】:

    保存 .ts 文件不会自动触发 Visual Studio 中的编译。您将需要构建/重建以触发编译。

    声明文件 (file.d.ts) 让 TypeScript 编译器可以从该文件中获取有关您正在使用的 JavaScript 库的更好的类型信息。您可以在一个文件或多个文件中定义所有接口;这不应该有任何区别。您还可以使用以下方式从外部库“声明”您正在使用的类型/变量:

    declare var x: number;
    

    这将告诉编译器将 x 视为一个数字。

    【讨论】:

    • 如果您尝试使用 jQuery 插件,则必须执行一个非常具体的步骤,因为您正在处理现有的 declare $: JQueryStatic; 定义。我将添加一个深入了解使用 jQuery 插件的细节的答案。
    【解决方案4】:

    我一直在寻找 jquery.inputmask 的 d.ts,最后我自己创建了一个简单的。它在

    https://github.com/jpirok/Typescript-jquery.inputmask

    或者你可以看下面的代码。

    它不会涵盖 jquery.inputmask 的所有情况,但可能会处理大多数情况。

        ///<reference path="../jquery/jquery.d.ts" />
    
    interface JQueryInputMaskOptions {
        mask?: string;
        alias?: string;
        placeholder?: string;
        repeat?: number;
        greedy?: boolean;
        skipOptionalPartCharacter?: string;
        clearIncomplete?: boolean;
        clearMaskOnLostFocus?: boolean;
        autoUnmask?: boolean;
        showMaskOnFocus?: boolean;
        showMaskOnHover?: boolean;
        showToolTip?: boolean;
        isComplete?: (buffer, options) => {};
        numeric?: boolean;
        radixPoint?: string;
        rightAlignNumerics?: boolean;
        oncomplete?: (value?: any) => void;
        onincomplete?: () => void;
        oncleared?: () => void;
        onUnMask?: (maskedValue, unmaskedValue) => void;
        onBeforeMask?: (initialValue) => void;
        onKeyValidation?: (result) => void;
        onBeforePaste?: (pastedValue) => void;
    }
    
    interface inputMaskStatic {
        defaults: inputMaskDefaults;
        isValid: (value: string, options: inputMaskStaticDefaults) => boolean;
        format: (value: string, options: inputMaskStaticDefaults) => boolean;
    }
    
    interface inputMaskStaticDefaults {
        alias: string;
    }
    
    interface inputMaskDefaults {
        aliases;
        definitions;
    }
    
    interface JQueryStatic {
        inputmask: inputMaskStatic;
    }
    
    interface JQuery {
        inputmask(action: string): any;
        inputmask(mask: string, options?: JQueryInputMaskOptions): JQuery;
    }
    

    【讨论】:

      【解决方案5】:

      在为插件创建自己的.d.ts 文件之前,您应该检查它是否已经作为DefinitelyTyped 库。例如,使用Typings,可以运行命令:

      typings install dt~bootstrap --global --save
      

      ...无需任何额外代码,您就可以访问各种 Bootstrap 插件。

      如果他们没有您正在寻找的插件,请考虑贡献您自己的定义。

      【讨论】:

      • 请注意,您可以使用TypeSearch 来查找库类型是否可用。
      猜你喜欢
      • 2017-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-16
      • 2018-10-04
      • 2017-10-02
      • 2018-01-30
      • 1970-01-01
      相关资源
      最近更新 更多