如何编写 TypeScript 声明文件

本文详细介绍了TypeScript声明文件(.d.ts)的作用、编写时机及方法,包括全局变量、npm包的声明方式,以及如何让TS自动生成声明文件。在使用非TS编写的第三方库或模块时,声明文件能提供类型信息,确保编译通过并保持与JS项目的兼容性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 什么是 TS 声明文件

在 TypeScript 中以 .d.ts 为后缀的文件,称为 TypeScript 声明文件。它的作用是描述 JavaScript 模块内所有导出接口的类型信息。

2. 什么时候需要写 TS 声明文件

在使用 TypeScript 开发的项目中,常常需要引入公共模块,或者第三方库。如果这些公共模块或第三方库是用 JS 写的,那么 TS 就无法检测到类型信息,在编译阶段会报错。

这时候有人会说,能不能将这些公共模块或第三方库的代码用 TS 重写呢?答案是不行,因为重写之后,使用这些库的 JS 项目就不兼容了,这些项目不能执行 TS 代码。

那么有没有一种方式,既可以让这些类库支持 TS ,又能兼容 JS 项目呢?有的,就是使用 TS 声明文件。例如我们有一个 index.js 文件,在同级目录下有一个 index.d.ts 声明文件:

- common
	|- index.js
	|- index.d.ts

当 TS 项目中引入了 index.js 模块,TS 默认会去同级目录下找同名的声明文件,这样 JS 模块就能具有类型了。而 JS 项目引入 index.js 模块,则会忽略这个声明文件。

在日常开发中,很多情况下我们不需要单独去编写 TS 声明文件。例如我们使用 TS 编写一个 npm 包,只要在编译的时候让 TS 自动生成声明文件,并在发布的时候将 .d.ts 文件一起发布即可。

但以下几种情况还是需要手动定义声明文件:

  1. 通过 script 标签引入的第三方库

    一些通过 CDN 引入的工具包(例如 jQuery),挂载了一些全局方法,如果在 TS 中直接使用的话,编译阶段会报错,这个时候就要对这些全局方法进行 TS 声明。

  2. 使用第三方 npm 包,但是没有提供声明文件

    第三方 npm 包如果有提供声明文件的话,一般会以两种形式存在:一是 @types/xxx ,二是在源码中提供 .d.ts 声明文件。第一种一般是使用率比较高的库会提供,可以通过 npm i @types/xxx 尝试安装。如果这两种都不存在的话,就需要我们自己来定义了。

  3. 项目中使用 JS 编写的公共模块

    本人现在做的项目,里面大部分是 JS 编写的,少数组件开始使用 TS 开发,对于一些公共模块,就必须手动添加声明文件,否则编译阶段就会报错了。

3. 如何编写 TS 声明文件

不同形式的声明文件,写法上有一定差异。还要注意,声明文件只是对类型的定义,不能进行赋值。

全局变量

全部变量的声明主要有以下几种语法:

declare let/const  // 声明全局变量
declare function   // 声明全局方法
declare class      // 声明全局类
declare enum       // 声明全局枚举类型 
declare namespace  // 声明(含有子属性的)全局对象
interface/type     // 声明全局类型,declare 可以不需要

这里需要注意的是只是定义类型,不能进行赋值

// 变量
declare let userName: string;
declare const wx: any;

// 函数,函数重载
declare function getName(uid: number): string;
declare function getName(): string;
declare function getName(cb: () => any): any;

// 类
declare class Course {
  cid: number;
  constructor(cid){};
  getCoursePrice(): number;
}

// 枚举
declare enum Status {
  Loading,
  Success,
  Failed,
}

// 接口,declare 可以不需要
interface CourseInfo {
  cid: number;
  name: string;
}
interface CGIData<T> {
  data: T;
  retcode: 0;
}

// 命名空间
declare namespace User {
  // 局部 Test.User
  interface User {
    name: string;
    age: number;
  }

  function getUserInfo(name: string): User {
    return "";
  }
  namespace fn {
    function extend(obj: any): any;
  }
}

// 声明合并
declare function User(id: number): string;

npm 包

对于没有提供声明文件的 npm 包,我们可以创建一个 types 目录,来管理自己写的声明文件,同时需要在配置文件 tsconfig.json 中的 path 和 baseUrl 中配置:

{
  "compilerOptions": {
    "module": "commonjs",
    "baseUrl": "./", // types文件夹的相对路径
    "paths": { "*": ["types/*"]}
  }
}

npm 包的声明文件主要有以下几种写法:

export const/let  // 导出变量
export namespace  // 导出(含有自属性的)对象
export default    // ES6 默认导出
export =          // commonjs 导出模块

拓展原有模块/全局变量

对于已经有声明定义的模块或者全局变量,可以利用 TS 中的声明合并对其进行拓展。

例如在 window 下挂载的一些全局变量:

interface Window {
  readonly request?: any;
  readonly devToolsExtension?: any;
  readonly wx?: any;
}

对已有模块进行拓展:

declare module "querystring" {
  function escape(str: string): string;
  function unescape(str: string): string;
}

还可以使用三斜线指令对声明文件进行引用:

/// <reference path=”custom.d.ts" />

4. 如何让 TS 在编译时自动生成 .d.ts 文件

只需要在 tsconfig.json 配置文件中开启即可,TS 编译时就会自动生成 .d.ts 声明文件:

{
  "compilerOptions": {
    "declaration": true
  }
}

参考

哥,帮忙写个声明文件呗

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值