详解如何编写一个Typescript的类型声明文件
本文详细讲解如何为JavaScript库编写TypeScript类型声明文件。通过自定义calculator库和axios库两个实例,演示如何定义函数、接口、重载及模块导出。涵盖d.ts文件创建、tsconfig配置、模块解析注意事项,以及如何将声明发布至@types供npm安装使用,帮助开发者实现类型安全。
类型声明文件概述
当前任务是为一个JavaScript编写的库创建对应的类型声明文件。
该库导出了一个函数calculator,其具体功能如下所示。
参考calculator.js文件内容。
// operator: 只能是 plus | minus
function calculator(operator, numbers) {
console.log(operator, numbers)
return
}
calculator.plus = (numbers) => {
return numbers
}
calculator.minus = (numbers) => {
return numbers
}
export default calculator首先分析calculator的结构。
该函数接收两个参数:第一个参数限定为plus或minus,第二个参数为数字数组。
此外,该函数还包含两个属性plus和minus,它们均接收数字数组作为参数。
自定义库类型声明实战
接下来逐步完善类型声明文件。
第一步,创建calculator.d.ts文件。由于calculator本质是一个函数,首先定义函数类型:
见calculator.d.ts文件内容。
type IOperator = 'plus' | 'minus'
type ICalculate = (operator: IOperator, numbers: number[]) => number
declare const calculator: ICalculate
export default calculator配置tsconfig.json:
"files": ["calculator.d.ts"]见index.ts文件内容。

此时,编写的类型声明文件已生效。
注意,在index.ts中引入calculator.js的函数时,calculator.d.ts文件中必须包含export default calculator,否则将报错提示calculator.d.ts不是一个模块。

然而,当尝试访问该函数的属性时,会出现报错。

这是因为仅声明了函数,而calculator还包含两个属性方法。解决方法是使用interface:
interface Icalculator {
(operator: Operator, numbers: number[]): number
plus(numbers: number[]): number
minus(numbers: number[]): number
}
至此任务完成。最后将声明文件提交至@types组织,并通过npm install @types/calculator下载,TypeScript即可自动读取此类声明文件。
注意:提交至@types时,类型文件命名必须为index.d.ts。
此时引入方式变为import calculator from 'calculator'。
复杂库类型定义示例
接下来查看一个axios库的类型定义文件编写方法。对axios类型声明文件进行精简,保留核心部分。
// 定义请求头的格式,即 key 只能是字符串,value 是一个联合类型 string | number | boolean
export type AxiosRequestHeaders = Record<string, string | number | boolean>;
// 定义了响应头的格式,即 key 和 value只能是字符串,同时利用 &(交叉类型) 把多个类型合并成一个类型
export type AxiosResponseHeaders = Record<string, string> & {
"set-cookie"?: string[]
};
// 对请求的参数进行转换,此处对应的就是转换函数
export interface AxiosRequestTransformer {
(data: any, headers?: AxiosRequestHeaders): any;
}
// 定义了所有请求方法的类型
export type Method =
| 'get' | 'GET'
| 'delete' | 'DELETE'
| 'head' | 'HEAD'
...
// 定义了所有返回数据的类型,可以是二进制,也可以是json对象
export type ResponseType =
| 'arraybuffer'
| 'blob'
| 'document'
| 'json'
...
// 请求配置AxiosRequestConfig是一个接口,接口传入了一个泛型,这个泛型就可以流入到里面的属性或值里面。
export interface AxiosRequestConfig<D = any> {
url?: string;
method?: Method | string;
baseURL?: string;
headers?: AxiosRequestHeaders;
params?: any;
data?: D;
responseType?: ResponseType;
...
}
// 请求返回的数据类型,定义了一个interface,里面有data,status等,同时传入了一个泛型,这个泛型可以流入到data里面,这样我就定义了data的类型
export interface AxiosResponse<T = any, D = any> {
data: T;
status: number;
statusText: string;
headers: AxiosResponseHeaders;
config: AxiosRequestConfig<D>;
request?: any;
}
// 定义了一个Axios的类,这个类定义了构造函数constructor,拦截器interceptors,以及一些调用方法get/post等
export class Axios {
constructor(config?: AxiosRequestConfig);
defaults: AxiosDefaults;
interceptors: {
request: AxiosInterceptorManager<AxiosRequestConfig>;
response: AxiosInterceptorManager<AxiosResponse>;
};
get<T = any, R = AxiosResponse<T>, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
post<T = any, R = AxiosResponse<T>, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
...
}
// AxiosPromise 继承于 Promise<AxiosResponse<T>>,Promise<AxiosResponse<T>>里面传入了泛型,这样泛型流入到AxiosResponse里面
export interface AxiosPromise<T = any> extends Promise<AxiosResponse<T>> {
}
// 定义了一个Axios实例的接口
export interface AxiosInstance extends Axios {
(config: AxiosRequestConfig): AxiosPromise;
(url: string, config?: AxiosRequestConfig): AxiosPromise;
}
export interface AxiosStatic extends AxiosInstance {
create(config?: AxiosRequestConfig): AxiosInstance;
Axios: typeof Axios;
...
}
declare const axios: AxiosStatic;
export default axios;首先引入import axios from 'axios',其类型为AxiosStatic,该类型包含create方法:
export interface AxiosStatic extends AxiosInstance {
create(config?: AxiosRequestConfig): AxiosInstance;
Axios: typeof Axios;
...
}执行create方法后,返回类型为AxiosInstance的变量:
export interface AxiosInstance extends Axios {
(config: AxiosRequestConfig): AxiosPromise;
(url: string, config?: AxiosRequestConfig): AxiosPromise;
}该变量首先是一个函数,支持两种调用方式:(config: AxiosRequestConfig): AxiosPromise; 或 (url: string, config?: AxiosRequestConfig): AxiosPromise;。同时它继承自Axios类型,拥有get、post等方法,因此具备如下使用方式:
import axios from 'axios'
const axiosInstance = axios.create()
// 发送请求的三种方式
axiosInstance({ url: 'test.url'})
axiosInstance(url: 'test.url', config: { method: 'get' })
axiosInstance.get('test.url')本文关于如何编写TypeScript类型声明文件的介绍到此结束。更多相关TypeScript类型声明文件内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!
什么时候该用JS构造器:与工厂模式、字面量的选择对比
2026-11-05 16:18:22
推荐几款轻量级JS照片墙开源库及对比
2026-11-05 15:56:19
JavaScript递归写法有哪些常见陷阱及避免方法
2026-11-05 14:53:38
JS数组浅拷贝与深拷贝怎么选?场景与方法总结
2026-11-05 14:41:02
p5.js 中 setup() 和 draw() 函数的执行机制详解
2026-11-05 12:32:38








