注册
web

终于搞懂类型声明文件.d.ts和declare了,原来用处如此大



项目中的.d.ts和declare


最近开发项目,发现公司代码里都有一些.d.ts后缀的文件



还有一些奇奇怪怪的declare代码



秉持着虚心学习的态度,我向同事请教了这些知识点,发现这些东西居然蛮重要的。于是,我根据自己的理解,把这些知识简单总结一下。


类型声明文件.d.ts


为什么需要 .d.ts 文件?


如果我们在ts项目中使用第三方库时,如果这个库内置类型声明文件.d.ts,我们在写代码时可以获得对应的代码补全、接口提示等功能。


比如,我们在index.ts中使用aixos时:



当我们引入axios时,ts会检索aixos的package.json文件,并通过其types属性查找类型声明文件,查找到index.d.ts这个文件后,就会根据其内部配置进行语法提示。



但是如果某个库没有内置类型声明文件时,我们使用这个库,不会获得Ts的语法提示,甚至会有类型报错警告



像这种没有内置类型声明文件的,我们就可以自己创建一个xx.d.ts的文件来自己声明,ts会自动读取到这个文件里面的内容的。比如,我们在index.ts中使用"vue-drag",会提示缺少声明文件。


由于这个库没有@types/xxxx声明包,因此,我们可以在项目内自定义一个vueDrag.d.ts声明文件。


// vueDrag.d.ts
declare module 'vue-drag'

这个时候,就不会报错了,没什么警告了。


第三方库的默认类型声明文件


当我们引入第三方库时,ts会自动检索aixos的package.json文件,并通过其types属性查找类型声明文件,查找到index.d.ts这个文件后,就会根据其内部配置进行语法提示。比如,我们刚才说的axios




  • "typings"与"types"具有相同的意义,也可以使用它。
  • 主声明文件名是index.d.ts并且位置在包的根目录里(与index.js并列),你就不需要使用"types"属性指定了。

第三方库的@types/xxxx类型声明文件


如express这类框架,它们的开发时Ts还没有流行,自然没有使用Ts进行开发,也自然不会有ts的类型声明文件。如果你想引入它们时也获得Ts的语法提示,就需要引入它们对应的声明文件npm包了。


使用声明文件包,不用重构原来的代码就可以在引入这些库时获得Ts的语法提示


比如,我们安装express对应的声明文件包后,就可以获得相应的语法提示了。


npm i --save-dev @types/express


@types/express包内的声明文件



.d.ts声明文件


通过上述的几个示例,我们可以知道.d.ts文件的作用和@types/xxxx包一致,@type/xxx需要下载使用,而.d.ts是我们自己创建在项目内的。


.d.ts文件除了可以声明模块,也可以用来声明变量。


例如,我们有一个简单的 JavaScript 函数,用于计算两个数字的总和:


// math.js
const sum = (a, b) => a + b
export { sum }

TypeScript 没有关于函数的任何信息,包括名称、参数类型。为了在 TypeScript 文件中使用该函数,我们在 d.ts 文件中提供其定义:


// math.d.ts
declare function sum(a: number, b: number): number

现在,我们可以在 TypeScript 中使用该函数,而不会出现任何编译错误。


.ts 是标准的 TypeScript 文件。其内容将被编译为 JavaScript。


*.d.ts 是允许在 TypeScript 中使用现有 JavaScript 代码的类型定义文件,其不会编译为 JavaScript。


shims-vue.d.ts


shims-vue.d.ts 文件的主要作用是声明 Vue 文件的模块类型,使得 TypeScript 能够正确地处理 .vue 文件,并且不再报错。通常这个文件会放在项目的根目录或 src 目录中。


shims-vue.d.ts 文件的内容一般长这样:


// shims-vue.d.ts

declare module '*.vue' {
import { DefineComponent } from 'vue';
const component: DefineComponent<{}, {}, any>;
export default component;
}


  • declare module '*.vue' : 这行代码声明了一个模块,匹配所有以 .vue 结尾的文件。* 是通配符,表示任意文件名。
  • import { DefineComponent } from 'vue'; : 引入 Vue 的 DefineComponent 类型。这是 Vue 3 中定义组件的类型,它具有良好的类型推断和检查功能。
  • const component: DefineComponent<{}, {}, any>; : 定义一个常量 component,它的类型是 DefineComponent,并且泛型参数设置为 {} 表示没有 props 和 methods 的基本 Vue 组件类型。any 用来宽泛地表示组件的任意状态。
  • export default component; : 将这个组件类型默认导出。这样,当你在 TypeScript 文件中导入 .vue 文件时,TypeScript 就知道导入的内容是一个 Vue 组件。

declare


.d.ts 文件中的顶级声明必须以 “declare” 或 “export” 修饰符开头。


通过declare声明的类型或者变量或者模块,在include包含的文件范围内,都可以直接引用而不用去import或者import type相应的变量或者类型。



  • declare声明一个类型

declare type Asd {
name: string;
}


  • declare声明一个模块

declare module '*.css';
declare module '*.less';
declare module '*.png';

.d.ts文件顶级声明declare最好不要跟export同级使用,不然在其他ts引用这个.d.ts的内容的时候,就需要手动import导入了


在.d.ts文件里如果顶级声明不用export的话,declare和直接写type、interface效果是一样的,在其他地方都可以直接引用


declare type Ass = {
a: string;
}
type Bss = {
b: string;
};

作者:快乐就是哈哈哈
来源:juejin.cn/post/7402891257196691468

0 个评论

要回复文章请先登录注册