稀土掘金技术社区 05月20日 09:56
xx.d.ts文件有什么用,为什么不引入都能生效?
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文深入探讨了TypeScript中.d.ts文件的作用和生效机制。.d.ts文件作为类型声明文件,主要用于为JavaScript代码、第三方库、非代码资源等补充类型信息,使得TypeScript编译器能够进行类型检查和代码提示。文章解释了为什么通过declare声明模块可以解决报错,以及.d.ts文件不引入也能生效的原因,包括tsconfig.json的配置、全局声明文件的识别和默认类型目录的使用。此外,还强调了并非任意.d.ts文件都能生效,只有在tsconfig.json中被包含且没有语法错误的文件才会被加载。

💡.d.ts文件是TypeScript的“翻译器”,负责描述代码的结构、类型和接口,使编译器能够理解代码并提供类型检查和自动补全等功能。

📚.d.ts文件可以为没有类型定义的JavaScript代码或第三方库补充类型声明,解决TypeScript编译器的报错问题,例如使用`declare var $: any;`为老旧的JS库声明类型。

🌍当.d.ts文件中没有import/export语句时,TypeScript会将其视为“全局类型声明文件”,自动合并到全局作用域中,使得声明的变量或类型在所有文件中可见,无需显式引入。

⚙️tsconfig.json配置文件决定了TypeScript编译器要包含和排除的文件、使用的类型库以及模块路径解析方式,.d.ts文件只有在tsconfig.json的include范围内才会被自动加载。

🧩可以使用模块扩展,给已有的模块添加自定义类型,不需要修改原始库代码,例如给vue-router添加auth?: boolean元数据。

原创 石小石Orz 2025-05-20 08:30 重庆

点击关注公众号,“技术干货”及时达!

点击关注公众号,“技术干货” 及时达!

背景简介

大家好,我是石小石!

在前端项目开发中,我们常常会遇到这样一种情况:「项目中引入了某个第三方库,但它没有提供内置的 TypeScript 类型声明」。此时,如果你在 TypeScript 项目中直接使用这个库,编译器就会报错。

也许你很聪明,知道在项目中的

shims-vue.d.ts

中通过 declare 声明此模块,来解决报错。

但你是否想过这些问题:

    为什么在

    .shims-vue.d.ts

    文件中写一个 declare 声明就能解决报错?

    .d.ts 文件明明没有显示引入,为什么就生效了?

    任意 xxx.d.ts 文件声明为什么都能发挥作用吗?

其实,能够写一行 

declare module 'xxx'

 就让 TypeScript 编译器 “闭嘴”,看似简单,背后却隐藏着 TypeScript 类型系统的一些核心机制。

.d.ts

 文件的作用

.d.ts

 文件是 TypeScript 世界中的 “翻译器”,它不负责运行代码,而是负责「描述代码的结构、类型、接口、模块」,使得 TypeScript 编译器 “明白” 你在干什么,从而让类型检查、提示、自动补全等功能得以正常运作。

    「为 JavaScript 代码或第三方库补充类型」

当你引入一个 「没有类型定义」 的库时,比如老旧的 JS 库或某些 npm 包没有内置 TypeScript 类型,会导致 TS 编译器报错。这时你可以写一个 

.d.ts

 文件,手动声明它的类型:

// types/jquery.d.tsdeclare var $: any;

    「为非代码资源声明模块(如 SVG、CSS、JSON 等)」

在项目中引入非代码资源时,TypeScript 默认是无法识别的,比如:

import logo from './logo.svg';

会报错:找不到模块。这时就需要一个 

.d.ts

 文件来告诉 TS 这是什么类型:

// types/shims-svg.d.tsdeclare module '*.svg' {  const content: string;  export default content;}

    「定义全局变量或类型」

比如 

VITE_APP_VERSION

 是在构建时注入的变量,你可以这样声明:

// types/global.d.tsdeclare const VITE_APP_VERSION: string;

这样就可以在任何文件中使用,不报错、还能获得类型提示。

    「定义环境变量、全局命名空间等复杂类型结构」

例如:

interface Window {  myGlobalAPI: () => void;}declare namespace MyLib {  type Options = {    debug: boolean;  };}

「补充已有模块的类型信息(模块扩展)」

你可以给已有模块添加自定义类型,不需要修改原始库代码:

// types/vue-router.d.tsimport 'vue-router';declare module 'vue-router' {  interface RouteMeta {    auth?: boolean;  }}

为什么写一个 

declare

 就能解决报错?

TypeScript 是强类型语言,它在编译时会尝试为每一个变量、函数、模块、类型标识符 “找到定义”。当我们引入一个没有类型声明的第三方模块时,比如:

import something from 'vs-tree';

如果 

vs-tree

 没有提供 

.d.ts

 文件(也就是没有类型定义),TypeScript 编译器就会报错:

但当你写上:

// shims-vue.d.ts 或任何 .d.ts 文件declare module 'vs-tree';

你就是「手动告诉 TypeScript」:“我知道这个模块存在,不用你担心类型问题。” 于是 TS 编译器不再报错,默认把它当作 

any

 类型处理。这其实是使用 

.d.ts

 的一个最基础场景:「模块声明补全」

为什么 

.d.ts

 文件不引入也能生效?

这要从 TypeScript 的文件识别机制说起。

TypeScript 在编译一个项目时,首先会加载项目根目录下的 

tsconfig.json

,它会根据其中的配置项决定:

    要包含哪些文件

    要排除哪些文件

    要使用哪些类型库(如 DOM、ESNext)

    要如何解析模块路径(如路径别名)

具体来说,

.d.ts

 文件能自动生效,主要有以下几种情况:

在 

tsconfig.json

 的 

include

 范围内

只要你的 

.d.ts

 文件路径在 

include

 的匹配范围内,TS 编译器就会自动加载它:

{  "include": ["src", "types"]}

如你把 

shims-vue.d.ts

 放在 

src/

 或 

types/

 下,它就会自动生效。

被编译器当作 “全局声明” 文件识别

.d.ts

 文件中如果没有 

import

/

export

,就会被 TypeScript 当作 “全局类型声明文件”(Global Declaration File),自动合并进全局作用域。这种文件中的内容对所有文件可见:

// types/global.d.tsdeclare const __APP_VERSION__: string;

你在任意 .ts 文件中都能直接使用 

__APP_VERSION__

,不需要任何引入。

被放置在默认类型目录下(如 

@types

TypeScript 默认会去 

node_modules/@types

 中找类型定义(社区维护的 DefinitelyTyped 类型库)。如果你把声明文件放进这个路径,甚至可以模拟 npm 包类型的形式存在。

任意 

xxx.d.ts

 文件都能生效吗?

并不是,之前已经提到,只有在 tsconfig.json 中的 

include

中被包含,编译器才会自动加载。
如上图,只有 src 目录下的任意

xx.d.ts

才会被自动加载。但以下情况,即使在 include 中声明也不会被加载。

失败原因

解释

使用了模块语法(如 

import

/

export

)导致该文件不再是全局声明

编译器不会自动把它合并为全局作用域

语法错误

编译器会跳过整个文件


关注更多AI编程资讯请去AI Coding专区:https://juejin.cn/aicoding

""~

阅读原文

跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

.d.ts文件 TypeScript 类型声明 tsconfig.json 模块声明
相关文章