TypeScript-给第三方库添加声明文件

1. 前言

在使用TypeScript写程序的时候,可能会需要使用到JavaScript库,因为历史遗留问题,现在非常多的第三方库依然是用JavaScript进行编写,但是大多数情况下,库的所有者已经帮你写好了TypeScript声明文件,即x.d.ts文件。

还有一些情况是库中并没有附带ts声明文件,但是可以通过:

npm i @types/xxx -s   # xxx为第三方JavaScript库的名字

进行下载该类型的库的声明文件。

上面两种方法都是用在别人已经帮你编写了声明文件的情况下,但是如果上面两种方式都无效,怎么自行编写声明文件呢?

2. 声明文件

因为工作原因,需要在Vue中使用到qqmap这个由腾讯提供的地图插件,通过上面的两种方式,都没有找到别人已经编写好的ts声明文件,在网上看了很多教程,也是云里雾里,感觉人家已经很努力的描述怎么编写声明文件,但是我就是看不懂。

后面研究了一下发现,其实非常简单,比如要使用qqmap这个js库,直接在src文件夹的任意地方创建一个qqmap.d.ts文件(不过还是推荐放到@types文件夹中)。

然后在qqmap.d.ts文件中编写声明:

declare module "qqmap";

好的,这些就大工告成了,直接ts文件中使用

import qqmap from "qqmap";

就可以引入这个第三方JavaScript库,但是,如果要用这个库中的方法,比如说qqmap.xxx(),这个时候又会开始报错,例如下面的代码:

maps.init("(你的KEY)", () => {
  const myLatlng = new maps.LatLng(this.lat, this.lng);
  const myOptions = {
    zoom: 15,
    center: myLatlng,
    mapTypeId: maps.MapTypeId.ROADMAP
  };
  const map = new maps.Map(
    document.getElementById("qqmap" + shortid),
    myOptions
  );
  //地址和经纬度之间进行转换服务
  const geocoder = new maps.Geocoder();
  //设置服务请求成功的回调函数
  geocoder.setComplete((result: { detail: { location: string } }) => {
    map.setCenter(result.detail.location);
    new maps.Marker({
      map: map,
      position: result.detail.location
    });
  });
  //若服务请求失败,则运行以下函数
  geocoder.setError(function() {
    alert("出错了,请输入正确的地址!!!");
  });
  geocoder.getLocation("成都市");
});

可以看到上面的例子中,不光有普通的.xxx()形式,还使用到了构造函数,比如new maps.LatLng(),这一段的声明即为:

const LatLng: LatLngFactory;

interface LatLngFactory {
  new (e: number, n: number);
}

即在接口中声明一个new ()的形式。

如果实例还涉及到调用方法,例如:const geocoder = new maps.Geocoder();geocoder.setComplete()

这一段的声明即为:

interface Geocoder {
  new ();

  setComplete(p: (result: Object) => void): Function;
}

const Geocoder: Geocoder;

依照上面的格式,只要发现报错,就到声明文件中进行声明,PS:这种没有现成声明文件的js文件用起来真是非常的麻烦,而且还会出现一个情况,就是你有时候并不能判断某个值到底是什么类型,只有凭感觉给它一个类型。

3. 最后

其实本来还准备长篇大论的,结果发现我自身对于TypeScript的声明就不是很了解,也没有找到比较靠谱的视频或者教程,所以暂且到这里吧,如果以后有碰到,再说。