詳解如何編寫一個Typescript的類型聲明文件
現(xiàn)在有這樣一個任務:給一個用 javascript 包寫一個類型文件。
這個包導出了一個函數(shù)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的結(jié)構(gòu)。
它首先是一個函數(shù),這個函數(shù)傳遞兩個參數(shù),第一個參數(shù)只能是plus和minus,第二個參數(shù)是一個數(shù)字數(shù)組。
其次,它有兩個屬性,分別是plus和minus,參數(shù)都是一個數(shù)字數(shù)組。
下面就來一步步完善這個類型文件。
第一步,創(chuàng)建一個 calculator.d.ts 文件。因為 calculator 本身是一個函數(shù),可以先定義一個函數(shù)類型:
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的函數(shù)時,calculator.d.ts文件中也一定要加上export default calculator,否則會報錯,報calculator.d.ts不是一個模塊。

但當我們訪問這個函數(shù)的屬性時,會報錯:

這是因為我們只聲明它是一個函數(shù),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 是一個聯(lián)合類型 string | number | boolean
export type AxiosRequestHeaders = Record<string, string | number | boolean>;
// 定義了響應頭的格式,即 key 和 value只能是字符串,同時利用 &(交叉類型) 把多個類型合并成一個類型
export type AxiosResponseHeaders = Record<string, string> & {
"set-cookie"?: string[]
};
// 對請求的參數(shù)進行轉(zhuǎn)換,此處對應的就是轉(zhuǎn)換函數(shù)
export interface AxiosRequestTransformer {
(data: any, headers?: AxiosRequestHeaders): any;
}
// 定義了所有請求方法的類型
export type Method =
| 'get' | 'GET'
| 'delete' | 'DELETE'
| 'head' | 'HEAD'
...
// 定義了所有返回數(shù)據(jù)的類型,可以是二進制,也可以是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;
...
}
// 請求返回的數(shù)據(jù)類型,定義了一個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的類,這個類定義了構(gòu)造函數(shù)constructor,攔截器interceptors,以及一些調(diào)用方法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>>里面?zhèn)魅肓朔盒?,這樣泛型流入到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',這個 axios 的類型就是 AxiosStatic,這個類型上有個 create 的方法:
export interface AxiosStatic extends AxiosInstance {
create(config?: AxiosRequestConfig): AxiosInstance;
Axios: typeof Axios;
...
}執(zhí)行 create 方法后,返回一個類型為 AxiosInstance 的變量:
export interface AxiosInstance extends Axios {
(config: AxiosRequestConfig): AxiosPromise;
(url: string, config?: AxiosRequestConfig): AxiosPromise;
}這個變量首先是一個函數(shù),這個函數(shù)可以這么使用(config: AxiosRequestConfig): AxiosPromise;,也可以這么使用(url: string, config?: AxiosRequestConfig): AxiosPromise;,同時它也繼承了Axios類型,Axios類型有g(shù)et, post等方法,所以它就有了如下使用方法:
import axios from 'axios'
const axiosInstance = axios.create()
// 發(fā)送請求的三種方式
axiosInstance({ url: 'test.url'})
axiosInstance(url: 'test.url', config: { method: 'get' })
axiosInstance.get('test.url')到此這篇關(guān)于詳解如何編寫一個Typescript的類型聲明文件的文章就介紹到這了,更多相關(guān)Typescript類型聲明文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript內(nèi)置對象math,global功能與用法實例分析
這篇文章主要介紹了JavaScript內(nèi)置對象math,global功能與用法,結(jié)合實例形式分析了javascript中內(nèi)置對象math與global的基本概念、功能及使用方法,需要的朋友可以參考下2019-06-06
微信小程序?qū)崿F(xiàn)給嵌套template模板傳遞數(shù)據(jù)的方式總結(jié)
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)給嵌套template模板傳遞數(shù)據(jù)的方式,結(jié)合實例形式總結(jié)分析了微信小程序嵌套template模板的定義、調(diào)用、參數(shù)傳遞及相關(guān)使用技巧,需要的朋友可以參考下2017-12-12
老生常談javascript中邏輯運算符&&和||的返回值問題
下面小編就為大家?guī)硪黄仙U刯avascript中邏輯運算符&&和||的返回值問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-04-04
js實現(xiàn)調(diào)用網(wǎng)絡攝像頭及常見錯誤處理
這篇文章主要介紹了js實現(xiàn)調(diào)用網(wǎng)絡攝像頭及常見錯誤處理,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-03-03
JavaScript輕松創(chuàng)建級聯(lián)函數(shù)的方法示例
級聯(lián)函數(shù)也叫鏈式函數(shù),方法鏈一般適合對一個對象進行連續(xù)操作 (集中在一句代碼)。一定程度上可以減少代碼量,缺點是它占用了 函數(shù)的返回值。下面這篇文章主要給大家介紹了利用JavaScript如何輕松創(chuàng)建級聯(lián)函數(shù)的方法示例,需要的朋友可以參考借鑒。2017-02-02

