# TypeScript 类型声明文件

# 1. 概述

说明:

  • 类型声明文件:用来为已存在的 JS 库提供类型信息
  • 在 TS 中使用这些库时,就像 TS 一样,会有代码提示、类型保护等

示例:

import axios from "axios";

// node_modules/axios/index.d.ts

axios({
  url: ''
})

# 2. TS 中的两种文件类型

分别为:

  • .ts 文件
  • .d.ts 文件,类型声明文件

比较:

文件 内容 编译 用途
.ts 类型信息、可执行代码 编译为 .js 文件 编写程序代码
.d.ts 类型信息 不会生成 .js 文件 为 JS 提供类型信息

总结:

  • .ts 是 implementation(代码实现文件)
  • .d.ts 是 declaration (类型声明文件)

# 3. 类型声明文件的使用

在使用 TS 开发项目时,类型声明文件的使用有以下两种方式:

  1. 使用已有的类型声明文件
  2. 创建自己的类型声明文件

# 3.1. 使用已有的类型声明文件

已有的类型声明文件,有两种情况:

  1. 内置类型声明文件
  2. 第三方库的类型声明文件

# 3.1.1. 内置类型声明文件

说明:

  • TS 为 JS 运行时可用的所有标准化内置 API 都提供了声明文件
  • 比如:
    • lib.es5.d.ts
    • lib.dom.d.ts

# 3.1.2. 第三方库的类型声明文件

第三方库的类型声明文件有两种存在方式:

  1. 库自带类型声明文件
  2. 由 DefinitelyTyped 提供
# 3.1.2.1. 库自带类型声明文件

说明:

  • 导入该库时,TS 自动加载库的类型声明文件
  • 通过 package.json 中的 types 字段指定类型声明文件的位置

示例:

  • 目录:

    proj/
        node_modules/
            axios/
                index.js
                index.d.ts
                package.json
    
  • package.json:

    {
      "types": "index.d.ts"
    }
    
# 3.1.2.2. DefinitelyTyped

说明:

  • DefinitelyTyped 是一个 github 仓库,提供高质量的第三方库类型声明文件,官网 (opens new window)
  • 安装某个库(包名为 xyz)的类型声明包:npm i -D @types/xyz。TS 会自动加载该类型声明包

示例:

  • 安装:

    npm i lodash
    npm i -D @types/lodash
    
  • 使用:

    import lodash from 'lodash';
      
    let num: number = lodash.add(1, 2);
    

# 3.2. 创建自己的类型声明文件

有两种情况需要自己创建类型文件:

  1. 项目内共享类型
  2. 为已有 JS 文件提供类型声明

# 3.2.1. 项目内共享类型

说明:

  • 多个 .ts 文件使用同一个类型,可以将该类型抽取到 .d.ts 文件中
  • .d.ts 文件,定义并导出 类型;.ts 文件,导入并使用 .d.ts 文件定义好的类型
  • 导入 .d.ts 文件时,.d.ts 后缀要省略

示例:

  • 目录:

    proj/
      main.ts
      index.d.ts
    
  • index.d.ts:

    export type Props = { x: number, y: number };
    
  • main.ts:

    import { Props } from "./index";
    
    let obj: Props = { x: 1, y: 2 }
    

# 3.2.2. 为已有 JS 文件提供类型声明

说明:

在 TS 项目中使用 .js 文件:

  • TS 项目中也可以使用 .js 文件
  • 导入 .js 文件时,TS 会自动加载与 .js 同名的 .d.ts 文件,以提供类型声明

declare 关键字:

  • 用于类型声明,为其他地方(如 .js 文件)已存在的变量声明类型,而不是创建一个新的类型
  • 对于 type、interface 等 TS 独有的类型,可以省略 declare 关键字
  • 对于 let、function 等 TS、JS 都可以使用的,应该使用 declare 关键字,明确指出为类型声明

示例:

  • utils.js:

    let count = 10;
    
    let position = {
      x: 0,
      y: 0,
    }
    
    let changePosition = (point) => {
      position = point;
      console.log('当前坐标点', position);
    }
    
    function add(num1, num2) {
      return num1 + num2;
    }
    
    export {
      count,
      position,
      changePosition,
      add,
    }
    
  • utils.d.ts:

    declare let count: number;
    
    interface Point {
      x: number,
      y: number,
    }
    
    declare let position: Point;
    
    declare let changePosition: (point: Point) => void;
    
    declare function add(num1: number, num2: number): number
    
    export {
      count,
      position,
      changePosition,
      add,
    }
    

# 4. 自定义第三方库类型声明文件

# 4.1. 在 window 对象上自定义属性

类型文件:

  • shims-window.d.ts

    interface Window {
      lw_name: string,
      lw_sayHello: () => void,
    }
    
    

# 4.2. click-outside-vue3

类型文件:

  • click-outside.d.ts

    /* eslint-disable no-var,vars-on-top */
    
    declare module 'click-outside-vue3' {
      var directive: any;
    
      function install();
    }
    

使用:

import vClickOutside from 'click-outside-vue3';

export default defineComponent({
  directives: {
    clickOutside: vClickOutside.directive,
  },
});
本章目录