用 @types 前缀的包是什么?有什么用?

前言

解决过 TypeScript 的项目大概都是从两个方向,Vue3 方向和 React Native 方向,而在 React Native 方向上我经常会遇到一个烦人的错误

Could not find a declaration file for module ‘juejin-type-study’. ‘d:/fe-project/nodejs/types-study/node_modules/juejin-type-study/main.js’ implicitly has an ‘any’ type.> Try npm i --save-dev @types/types-study if it exists or add a new declaration (.d.ts) file containing declare module 'juejin-type-study';

PS: juejin-type-study 代指 npm 包,也是文章的例子

这个问题的场景通常出现于 ts 项目中引用包时会出现

// main.ts
import { util } from "juejin-type-study";

util(); 

PS: ts 指代 TypeScript

用 @types 前缀的包是什么?有什么用?_第1张图片

问题起因

ts 作为一个有类型的语言,在 .ts 文件引用包时,默认时必须要有类型声明的,不能是 any,而 ts 对于包(module)的类型声明要求为提供 .d.ts,否则就要在 tsconfig.json 中声明

那么就有一个问题了,ts 是怎么找到包/模块的类型声明的?

TS 寻找类型规则

ts 对于包/模块的声明寻找规则如下

1.TypeScript 编译器先在当前编译上下文找模块的定义
2.如果找不到,则会去 node_modules 中的 @types(默认情况,目录可以修改,后面会提到)目录下去寻找对应包名的模块声明文件

说实话 TypeScript 的文档真的不怎样,虽然有中文文档,但文档整个的逻辑很乱,知识点东一块西一块,找起来很麻烦,像此类的寻址规则,通常文档会给出一个很严谨的描述,比如 Node.js 的模块寻址,但我在 ts 的文档里愣是半天没找着,等我找到了会更新一个更严谨的规则

作用

.ts 文件和 .js 文件不一样,对于 node.js 环境中 .js 有自己的模块寻址规则,而对于 ts 环境中 .ts 文件中的模块就是类型声明,ts 依靠类型声明来实现自己的功能,而 @types 其实就是类型声明的集中仓库,为 ts 项目中的引用提供类型说明

为什么需要 @types 这个目录?原因是过去很多模块/包是用的纯 JS 写的,没有类型声明,ts 就无法给到自动补全和智能提示等功能

下面就通过解决之前提出过的问题来解释实际中的 @types 是咋用的

创建 Module

在此之前我们需要一个模块来作为项目中引用的 Module,毕竟 @types 中包含的就是 Module 的类型声明

那没有 npm 包怎么办?需要去 npm 网站里创建一个吗?

实际上并不需要,了解过 Node.js 关于模块的寻址规则就可以直接在 node_modules 目录下伪造一个模块,具体原理可以参考这篇文章

node_modules 中创建一个 juejin-type-study 的目录,里面只需要包含两个文件,main.jspackage.json

用 @types 前缀的包是什么?有什么用?_第2张图片
// main.js
export const util = () => {
  console.log("Hello World");
}; 

创建 .d.ts

之前的 ts 给出一个警告中包含一个解决方案,其中如下

Try npm i --save-dev @types/types-study if it exists or add a new declaration (.d.ts) file containing declare module 'juejin-type-study';

里面提到可以创建一个 .d.ts 文件,包含 declare module 'juejin-type-study'; 就可以解决这个问题

实际操作就是在根目录下随便取个名字创建 .d.ts,通常为缺失类型声明的模块名称,如下

declare module 'juejin-type-study' {
  export function util(): void;
} 

_Module .d.ts 的模板可以查看文档
创建之后就不会再报错了,如下

用 @types 前缀的包是什么?有什么用?_第3张图片

@types 本质上也是一样,ts 会自动帮我们识别 .d.ts 的位置,默认是根目录和 /node_modules/@types/[libname]/index.d.ts

用 @types 前缀的包是什么?有什么用?_第4张图片

注意,VS Code 对于类型提示和警告似乎有缓存,如果将 .d.ts 迁移位置后仍然报错可以尝试删除模块引用重新输入

最后

整理了一套《前端大厂面试宝典》,包含了HTML、CSS、JavaScript、HTTP、TCP协议、浏览器、VUE、React、数据结构和算法,一共201道面试题,并对每个问题作出了回答和解析。

有需要的小伙伴,可以点击文末卡片领取这份文档,无偿分享

部分文档展示:



文章篇幅有限,后面的内容就不一一展示了

有需要的小伙伴,可以点下方卡片免费领取

你可能感兴趣的:(javascript,前端,react.js)