# TypeScript 的包名字 @type

**URL:** <https://www.isharkfly.com/t/typescript-type/15715>\
**Category:** 前端\
**Tags:** typescript\
**Created:** [May 6, 2024, 8:23pm UTC](https://www.isharkfly.com/t/typescript-type/15715 "2024-05-06T20:23:15Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![honeymoose](https://www.isharkfly.com/user_avatar/www.isharkfly.com/honeymoose/32/20796_2.png) [@honeymoose](https://www.isharkfly.com/u/honeymoose)\
**Post date:** [May 6, 2024, 8:23pm UTC](https://www.isharkfly.com/t/typescript-type/15715/1 "2024-05-06T20:23:15Z")

</div>

这里我通过一个例子来说明一下什么是 @types，这样大家理解起来更深刻一点。

当我们用 npm 等包管理工具安装第三方包的时候，有些包并不是 TypeScript 编写的，自然也不会导出 TypeScript 声明文件。这种情况下，如果我们在 TypeScript 项目中引入了这种包，则会编译报错(没有设置 allowJS)。举个例子，当我们通过`npm install jquery --save` 安装 jquery 包并引用的时候，TypeScript 会报错。

> ❝ allowJS 是 TypeScript 1.8 引进的一个编译项。  
> ❞

报错内容如下：

> ❝ Could not find a declaration file for module ‘jquery’. Try `npm install @types/jquery` if it exists or add a new declaration (.d.ts) file containing `declare module 'jquery';`  
> ❞

这里的意思是 TypeScript 没有找到 jquery 这个包的定义，你可以通过`npm install @types/jquery`安装相关声明，或者自己定义一份.d.ts 文件，并将 jquery 声明为 module。

全世界不是 TypeScript 编写的包多了去了。即使你的包是 TypeScript 编写的，如果你没有导出声明文件，也是没用的。（TypeScript 默认不会导出声明文件，只会编译输出 JavaScript 文件）。因此 TypeScript 必须对这种情况提供解决方案，而上面的两种方案（安装 @types 和 自己 declare module）就是 TypeScript 官方提出的， 你可以选择适合你的方案。我的推荐是尽量使用 @types 下的声明，实在没有，再使用第二种方法。

值得一提的是，并不是所有的包都可以通过这种方式解决的， 能解决的是 DefinitelyTyped 组织已经写好定义的包， 好消息是比较流行的包基本都有。

## **包类型定义的查找**

就好像 node 的包查找是先在当前文件夹找 node\_modules，在它下找递归找，如果找不到则往上层目录继续找，直到顶部一样， TypeScript 类型查找也是类似的方式。

具体来说就是：

- TypeScript 编译器先在当前编译上下文找 jquery 的定义。
- 如果找不到，则会去 node\_modules 中的@types （默认情况，目录可以修改，后面会提到）目录下去寻找对应包名的模块声明文件。

## **变量类型定义的查找**

和包查找类似，默认情况下变量类型定义的查找也会去 @types 下去寻找。只不过并不是直接去 @types 找，而是有一定的优先级， 这个过程类似原型链或者作用域链。

比如如下代码：

```auto
const user: User = { name: "lucifer" };

```

- Typescript 则会先在本模块查找 User 的定义。
- 如果找到，则直接返回。 如果找不到， 则会到全局作用域找，而这个全局默认就是指的就是 @types 下的所有类型定义。（注意目录页是可以配的）

> ❝ 也就是说 @types 下的定义都是全局的。当然你可以导入 @types 下导出的定义，使得它们的作用域变成你的模块内部。  
> ❞

## 搜索 Typed 包

根据官方的说法，搜索 Typed 的包，目前这个功能已经不需要了。

> **[Search for typed packages](https://www.typescriptlang.org/dt/search/)**
>
> This page is no longer necessary.

 ![2024-05-06_16-23-02](https://cdn.isharkfly.com/com-isharkfly-www/discourse-uploads/original/2X/1/17f95df1c97a1b4d418027a2c082e7253dc8febc.png)
