• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

编写.d.ts这样的类型定义文件

武飞扬头像
程序媛-静儿
帮助1

类型定义文件是帮助TS文件,去理解引入的JS库里的内容的。因为这些JS库里,没有TS要求的类型的概念。

我们写代码的时候,通常会遇到一个场景,引入一个类库,发现这个库是用js代码写的,然后ts里用这样的类库就会有问题,导致我们需要安装类库的类型定义文件。安装这样的类型定义文件是非常简单的,但是类型定义文件是怎么写的呢? 原理是什么呢?

  • 我们先在index.html里引入 jquery文件。
  1.  
    <!DOCTYPE html>
  2.  
    <html lang="en">
  3.  
    <head>
  4.  
    <meta charset="UTF-8">
  5.  
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6.  
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7.  
    <title>Document</title>
  8.  
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.js"></script>
  9.  
    <script src="./page.ts"></script>
  10.  
    </head>
  11.  
    <body>
  12.  
     
  13.  
    </body>
  14.  
    </html>
  • 然后我们可以在page.ts里调用jquery的方法,我们会发现,虽然可以运行,但是编辑器会飘红,告诉我们需要安装jquery 的类型文件。因为jquery 是JS写的。npm i --save-dev @types/jquery
  1.  
    $(function(){
  2.  
    alert(123);
  3.  
    })

学新通

image.png

现在我们不安装别人写的jquery 的类型定义文件,我们自己写一个类型定义文件 jquery.d.ts。帮助page.ts去理解jquery的JS语法。

  • 我们调用的$是一个函数,接收一个参数也是一个函数,$函数返回值是void。参数这个函数返回值也是void
  1.  
    $(function(){
  2.  
    alert(123);
  3.  
    })
  • 我们可以这样写,通过declare var定义全局变量;.d.ts 文件中的顶级声明必须以 "declare" 或 "export" 修饰符开头
  1.  
    //定义全局变量
  2.  
    declare var $: (params:()=>void) => void;
  • 我们刚才把$定义为一个全局变量。还可以把$定义为一个全局函数
  1.  
    // 定义全局函数
  2.  
    declare function $(params:()=>void): void;

函数重载,对一个函数名字,可以写多个全局函数声明。也就是说一个函数,可以有多种形式。

  • 当我们调用函数接收的参数是一个函数。而不是字符串
  1.  
    $(function(){
  2.  
    $('body').html('<div>123</div>');
  3.  
    })
  • 我们可以再次定义一个$全局函数声明,这次接收的参数是一个字符串,返回的是对象,对象里有一个属性html,这属性的类型也是函数,接收一个字符串参数,返回一个对象
  1.  
    declare function $(params: string): {
  2.  
    html: (html: string) => {};
  3.  
    };
  • 还可以写的更简洁一点
  1.  
    interface JqueryInstance {
  2.  
    html:(html:string)=>JqueryInstance
  3.  
    }
  4.  
    // 当传函数的时候,返回值是空
  5.  
    declare function $(readyFunc: () => void): void;
  6.  
    // 当传一个选择器的时候,返回值是一个juqery对象
  7.  
    declare function $(selector: string): JqueryInstance;

函数重载的另外一种写法.这种写法利用了interface 的一种特性,就是在接口里定义两个函数的实现的时候,实际上就是一种函数的重载。表示Jquery 可以有两种实现方式。

  1.  
    interface Jquery {
  2.  
    (readyFunc: () => void): void;
  3.  
    (selector: string): JqueryInstance;
  4.  
    }

当然,如果只是声明了Jquery 接口,那么$符号是不可以用的,所以可以定义一下$的类型。

  1.  
    interface Jquery {
  2.  
    (readyFunc: () => void): void;
  3.  
    (selector: string): JqueryInstance;
  4.  
    }
  5.  
     
  6.  
    declare var $: Jquery;

如何对对象进行类型定义,以及如何对类进行类型定义,以及命名空间的嵌套

  1.  
    // new $.fn.init();
  2.  
    declare namespace $ {
  3.  
    namespace fn {
  4.  
    class init {}
  5.  
    }
  6.  
    }
  7.  
     
  8.  
    $(function(){
  9.  
    $('body').html('<div>123</div>');
  10.  
    new $.fn.init();
  11.  
    })

总之,当我们引入外部的一个库,这个库可能会有一些全局的变量、方法、对象无法被typescript无法识别这些东西,我们就可以通过全局的声明的语法让typescript理解库里的这些东西。让我们在typescript里使用这些变量、方法、对象的时候不再报错。

  • 定义全局变量 用 declare var
  • 定义全局函数 用 declare function
  • 定义全局对象 用 declare namespace
  • 定义全局函数重载的时候,有了两种方式
  1.  
    declare function $(readyFunc: () => void): void;
  2.  
    declare function $(params: string): JqueryInstance;
  3.  
     
  4.  
    // interface Jquery {
  5.  
    // (readyFunc: () => void): void;
  6.  
    // (selector: string): JqueryInstance;
  7.  
    // }
  • 如果想要$即是函数又是对象的时候,用interface 就不合适了,还是需要用declare
  1.  
    declare function $(readyFunc: () => void): void;
  2.  
    declare function $(params: string): JqueryInstance;
  3.  
    declare namespace $ {
  4.  
    namespace fn {
  5.  
    class init {}
  6.  
    }
  7.  
    }

ES6的方式,如何通过.d.ts文件,声明一些模块。

  • 首先安装一下jquery npm install jquery --save.然后在page.ts里引入,会发现报错。原因是 我们的jquery.d.ts文件,并不是模块化声明的。

    学新通

    image.png

  • 下边我们模块化声明一下 jquery.d.ts。注意 declare 后边跟 module
  1.  
    // ES6 模块化
  2.  
    // 定义一个模块叫做jquery 和通过 import引入的 jquery要一致
  3.  
    declare module 'jquery' {
  4.  
    interface JqueryInstance {
  5.  
    html:(html:string)=>JqueryInstance
  6.  
    }
  7.  
     
  8.  
    // 混合类型
  9.  
    function $(readyFunc: () => void): void;
  10.  
    function $(params: string): JqueryInstance;
  11.  
    namespace $ {
  12.  
    namespace fn {
  13.  
    class init {}
  14.  
    }
  15.  
    }
  16.  
    }
学新通
  • 这个时候,通过 import引入的 。方法的引用还是会报错。原因是,当我们用模块化定义d.ts文件的时候,记得在最后一定要把外部要用的东西通过export导出去

    image.png

  1.  
    declare module 'jquery' {
  2.  
    interface JqueryInstance {
  3.  
    html:(html:string)=>JqueryInstance
  4.  
    }
  5.  
     
  6.  
    // 混合类型
  7.  
    function $(readyFunc: () => void): void;
  8.  
    function $(params: string): JqueryInstance;
  9.  
    namespace $ {
  10.  
    namespace fn {
  11.  
    class init {}
  12.  
    }
  13.  
    }
  14.  
    export = $
  15.  
    }
学新通
  • 这样,我们定义了一个jquery的模块,里边有关于jquery的混合类型的定义,最终我们把我们引入后,就可以拿到$上各种方法和命名空间。

这种是ES6的模块化方式,还有AMD的等等。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgghgge
系列文章
更多 icon
同类精品
更多 icon
继续加载