一文詳解為什么你的TypeScript項(xiàng)目里總會(huì)有幾個(gè).d.ts文件
前言
剛寫(xiě)TS那會(huì)兒,我看到項(xiàng)目里莫名其妙冒出個(gè)types.d.ts或者global.d.ts,心里是有點(diǎn)懵的。啥?這文件是干啥的?我 .ts文件不是已經(jīng)寫(xiě)類型了嗎?為啥還要多此一舉?
后來(lái),項(xiàng)目越做越大,第三方庫(kù)用得越來(lái)越多,加上團(tuán)隊(duì)里有人用JS、有人用TS,我才發(fā)現(xiàn)——.d.ts 文件,其實(shí)是個(gè)“救火隊(duì)員”。

一、啥時(shí)候你會(huì)突然需要.d.ts?
先說(shuō)個(gè)場(chǎng)景。
我們團(tuán)隊(duì)之前接入了一個(gè)老系統(tǒng),人家封裝了個(gè)JS工具庫(kù),叫legacy-utils.js,里面一堆函數(shù):
// legacy-utils.js
function formatDate(date) {
return date.toISOString().slice(0, 10);
}
function calculateTax(amount, rate) {
return amount * rate * 0.01;
}
我們?cè)赥S項(xiàng)目里直接 import:
import { formatDate } from './legacy-utils';
formatDate(new Date()); // 報(bào)錯(cuò):Could not find a declaration file...
紅了! VSCode一下就給你標(biāo)紅,說(shuō)“這玩意沒(méi)類型,我沒(méi)法檢查”。
這時(shí)候,你有兩個(gè)選擇:
- 改人家JS文件,變成
.ts—— 別想,那是別的團(tuán)隊(duì)維護(hù)的。 - 寫(xiě)個(gè)
.d.ts文件,告訴TypeScript:“別慌,我知道它有啥類型。”
于是,我默默在項(xiàng)目里建了個(gè)types/legacy-utils.d.ts:
// types/legacy-utils.d.ts
declare module 'legacy-utils' {
export function formatDate(date: Date): string;
export function calculateTax(amount: number, rate: number): number;
}
然后,在tsconfig.json里確保typeRoots包含了types目錄。
再回到代碼里,紅波浪線沒(méi)了,自動(dòng)補(bǔ)全也有了,世界清凈了。
那一刻我悟了:.d.ts 就是給JS打“類型補(bǔ)丁”的。
二、還有啥場(chǎng)景會(huì)用到它?
場(chǎng)景1:全局變量?別慌,.d.ts來(lái)兜底
有些老項(xiàng)目,喜歡把變量掛到window上:
// index.html
<script>
window.APP_CONFIG = { apiUrl: 'https://api.example.com' };
</script>
你在 TS 里寫(xiě):
console.log(window.APP_CONFIG.apiUrl); // 類型“Window & typeof globalThis”上不存在屬性“APP_CONFIG”
煩不煩?煩。
解決方法:建個(gè)global.d.ts:
// global.d.ts
interface Window {
APP_CONFIG: {
apiUrl: string;
};
}
保存,刷新,紅波浪線消失。舒服了。
我管這個(gè)叫“強(qiáng)行擴(kuò)展”,雖然有點(diǎn)野路子,但項(xiàng)目要上線,誰(shuí)還管你是不是優(yōu)雅。
場(chǎng)景2:第三方庫(kù)沒(méi)提供類型?自己寫(xiě)!
比如你用了某個(gè)小眾npm包,叫super-fast-hash,作者沒(méi)寫(xiě)類型,但你又不想用any(畢竟開(kāi)了 noImplicitAny)。
你可以:
// types/super-fast-hash.d.ts
declare module 'super-fast-hash' {
const hash: (input: string) => string;
export default hash;
}
然后你就可以:
import hash from 'super-fast-hash';
const result = hash('hello'); // 類型正確,不報(bào)錯(cuò)
雖然這庫(kù)可能就用一次,但至少代碼看起來(lái)“專業(yè)”了點(diǎn),對(duì)吧?
場(chǎng)景3:我想在多個(gè)文件里用同一個(gè)type,但不想到處import
比如我們項(xiàng)目里經(jīng)常用到一種“用戶狀態(tài)”:
type UserStatus = 'active' | 'inactive' | 'pending';
如果每個(gè)文件都import,太麻煩。不如:
// types/global-types.d.ts type UserStatus = 'active' | 'inactive' | 'pending';
然后在 tsconfig.json 里加:
{
"compilerOptions": {
"typeRoots": ["node_modules/@types", "types"]
}
}
這樣,所有 .ts文件里都能直接用UserStatus,不用import。
是不是有點(diǎn)“全局污染”?是。但小項(xiàng)目圖個(gè)省事。
三、.d.ts文件的潛規(guī)則
文件名無(wú)所謂,但最好有意義
比如axios.d.ts、env.d.ts,一看就知道是干啥的。內(nèi)容只能是類型相關(guān)
你不能在.d.ts里寫(xiě)const x = 1,會(huì)報(bào)錯(cuò)。它只能有type、interface、declare這些。declare module 是“聲明模塊”的全能鑰匙
第三方庫(kù)沒(méi)類型?用它!JS 文件想加類型?用它!別濫用,小心“類型幻覺(jué)”
你寫(xiě)了個(gè)declare const api: any;,確實(shí)不報(bào)錯(cuò)了,但等于啥也沒(méi)做。類型檢查形同虛設(shè),別騙自己。
結(jié)尾
.d.ts文件用得好,它讓你的項(xiàng)目更健壯;用得爛,它讓你的類型系統(tǒng)變成“皇帝的新衣”。
(寫(xiě)完這篇,我回頭看了看項(xiàng)目里的十幾個(gè) .d.ts 文件,嘆了口氣:是時(shí)候重構(gòu)了……)
到此這篇關(guān)于為什么你的TypeScript項(xiàng)目里總會(huì)有幾個(gè).d.ts文件的文章就介紹到這了,更多相關(guān)TS項(xiàng)目為何有.d.ts文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js金額千分位的6種實(shí)現(xiàn)方法實(shí)例
在前端開(kāi)發(fā)中經(jīng)常會(huì)遇到這樣一種需求,使用Javascript格式化數(shù)字進(jìn)行輸出,下面這篇文章主要給大家介紹了關(guān)于js金額千分位的6種實(shí)現(xiàn)方法,需要的朋友可以參考下2022-03-03
在js文件中如何獲取basePath處理js路徑問(wèn)題
在jsp中,我們可以用el表達(dá)式直接獲取basePath,但是在單獨(dú)js文件中不能用el表達(dá)式,下面與大家分享下js文件中如何獲取basePath,感興趣的朋友可以參考下2013-07-07
使用HTML+JavaScript實(shí)現(xiàn)可編輯表格的方法
可編輯表格是數(shù)據(jù)管理系統(tǒng)中的重要組件,它將數(shù)據(jù)展示與編輯功能融為一體,使用戶能夠直接在表格界面中修改數(shù)據(jù)內(nèi)容,本文將介紹如何使用 HTML、CSS 和 JavaScript 實(shí)現(xiàn)一個(gè)可編輯表格,需要的朋友可以參考下2026-01-01
node.js使用nodemailer發(fā)送郵件實(shí)例
這篇文章主要介紹了node.js使用nodemailer發(fā)送郵件的方法,例子中使用的是QQ郵箱,你也可以修改成其它的郵箱如163、gmail等,需要的朋友可以參考下2014-03-03
基于javascript實(shí)現(xiàn)貪吃蛇小游戲
這篇文章主要介紹了基于javascript實(shí)現(xiàn)貪吃蛇小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
Javascript 5種方法實(shí)現(xiàn)過(guò)濾刪除前后所有空格
這篇文章主要介紹Javascript 5種過(guò)濾刪除前后所有空格的方法,比較實(shí)用,需要的朋友可以參考下。2016-06-06
Express實(shí)現(xiàn)前端后端通信上傳圖片之存儲(chǔ)數(shù)據(jù)庫(kù)(mysql)傻瓜式教程(二)
這篇文章主要介紹了Express實(shí)現(xiàn)前端后端通信上傳圖片之存儲(chǔ)數(shù)據(jù)庫(kù)(mysql)傻瓜教程(二)的相關(guān)資料,需要的朋友可以參考下2015-12-12

