调整项目目录结构
在项目中使用 TypeScript 并不仅仅是为了让代码中的类型更加明确,对于有些还没学习过 TypeScript 的部分朋友有些本能的排斥,这是很正常的现象。 但是在项目中使用 TypeScript 其实和框架中使用 TypeScript 是完全不一样的,对于不懂 TypeSctipt 的朋友(当然现在不懂的挺少的吧!嘻嘻嘻)你就当做 js 写,只是把文件后缀从 jsx
换成 tsx
,剩下的事情交给 VS Code。
给 Umi 项目添加 TypeScript 支持
你可以参照 TypeScript 官方文档,手动添加配置和使用,但是在 Umi 最简单方式还是使用微生成器,上一节课中,我们介绍了很多微生成器,其实如果你记不住或者说懒得记。你可以直接执行 npx umi g
,Umi 会给出当前项目中支持的微生成器。
$ cd boilerplate $ npx umi g ? Pick generator type › - Use arrow-keys. Return to submit. ❯ Create Pages -- Create a umi page by page name Enable Prettier -- Setup Prettier Configurations Enable Typescript -- Setup tsconfig.json Enable Jest -- Setup Jest Configuration Enable Tailwind CSS -- Setup Tailwind CSS configuration Enable Dva -- Configuration, Dependencies, and Model Files for Dva Generate Component -- Generate component boilerplate code Generate mock -- Generate mock boilerplate code Generator api -- Generate api route boilerplate code 复制代码
我们通过上下方向键,选中我们需要的微生成器,比如现在我们选择 Enable Typescript -- Setup tsconfig.json
.
✔ Pick generator type › Enable Typescript -- Setup tsconfig.json info - Write package.json info - Write tsconfig.json ... ... Progress: resolved 727, reused 701, downloaded 0, added 13, done devDependencies: + typescript 4.7.2 复制代码
umi typescript 是否正确配置
判断 Umi typescript 是否正确配置非常的简单,只要看所有从 umi import 的内容是否全部“未找到”。
import { Link, useSearchParams, createSearchParams, useLocation } from "umi"; // 以上所有的引用都会标红,错误是 模块“"umi"”没有导出的成员“XXXXX” 复制代码
如果未正确配置,则修改 tsconfig.json
。
修改 tsconfig.json
Umi typescript 部分的生成器还没有完全完成,后续还有 LSP 之类的功能,因此此时生成的
tsconfig.json
文件中的paths
针对于项目的话是有错误的。
将 paths
改为正确的,能够指到 Umi 临时文件目录
"paths": { "@/*": ["*"], "@@/*": [".umi/*"] }, 复制代码
改成
"paths": { "@/*": ["./src/*"], "@@/*": ["./src/.umi/*"] }, 复制代码
如果你的 tsconfig 已经是正确的,那就不用修改。
修改文件后缀
修改文件名 src/pages/index.jsx
为 src/pages/index.tsx
这时你将看到项目标红,鼠标移到标红的位置上,可以看到错误提示:““React”指 UMD 全局,但当前文件是模块。请考虑改为添加导入。ts(2686)” 要修复这个错误需要我们在文件的头部,引入 import React from "react";
引入之后发现文件中的错误修复了,但是 import react 这里又有一个新的错误,再次将鼠标移到标红的位置上,你讲看到一个新的错误提示:“找不到模块“react”或其相应的类型声明。ts(2307)”
一般 ts 提示找不到模块,要么就是没有安装,要么就是安装的库没有类型。我们可以在项目中安装对应的类型库,如
pnpm i @types/react --D 复制代码
修复完之后,继续查看页面中存在标红的位置,你可以在 createSearchParams
看到标红,鼠标移上去看到一个错误:“类型“{ a: number; b: number; }”的参数不能赋给类型“URLSearchParamsInit | undefined”的参数。属性“a”的类型不兼容。不能将类型“number”分配给类型“string | string[] | undefined”。ts(2345)”
setSearchParams(createSearchParams({ a: 123, b: 456 })); // ERROR: // 类型“{ a: number; b: number; }”的参数不能赋给类型“URLSearchParamsInit | undefined”的参数。 // 属性“a”的类型不兼容。 // 不能将类型“number”分配给类型“string | string[] | undefined”。ts(2345) 复制代码
将 123
和 456
改成 '123'
和 '456'
。
自此,我们修复了当前页面的全部类型错误。看上面的行文,你会发现,我一直在强调“查看编辑器标红,然后鼠标移上去查看错误”,因为这个操作你要形成一种下意识的动作,一定要将页面中的标红全部清空,不能容忍哪怕一处“标红”,因为如果你容忍了一处“标红”,你就会下意识的忽略“标红”,后面你会发现,越复杂的页面你的“标红”错误更多。
还有聊聊好处,我们从 url 中取下来的值,会是全部都是字符串的,如果你在传参的时候写的是数字,也会被“默认”转成字符串,这在理解的时候又要耗费心智成本,所以这里类型提醒,会促使我们在传参的时候,就传递字符串。
以上操作重复一遍,修改
src/pages/user.jsx
为src/pages/user.tsx
智能提示和补全
先聊聊使用 typescript 最直观的好处,那就是智能提示和补全了,当你需要从一个库导出一个 Api 时,可能你只需要输入首字母,VS Code 就会自动罗列出这个库导出的全部 Api,如
import { u } from "umi"; // 当你输入一个 'u' // 你将会看到如下列表 // useAppData // useClientLoaderData // useLocation // useMatch // useNavigate // useOutlet // useOutletContext,useParams,useResolvedPath ... 复制代码
毫无疑问,这样确实可以极大的提升开发者体验。
不仅如此,Umi 还做的更多,Umi 是使用插件方式扩展框架能力的,意味着,很多能力和 Api 并不是内置集成在框架中的,所以 Umi 提供的所有 Api 的清单,和你当前项目使用到的所有插件直接相关。Umi 提供了 import all in umi
的能力,可以较少你少写很多的 import
。
这个的实现其实也很简单,在 umi 中导出 @@/exports
中的所有导出,我们前面配置 tsconfig.json
的时候,有写到 "@@/*": ["./src/.umi/*"]
,因此 @@/exports
就会被映射到 ./src/.umi/exports
。
插件中需要导出的 Api,通过通过 Umi 插件的 Api 写入 ./src/.umi/exports
文件中。所以如果后续你遇到一个 Api 无法工作或者提示找不到,你就可以直接先到这个文件下查看,“导出”是否被正确写入,这将有利于你定位和解决这一类问题。
当然如果你在向其他人请教问题或者提交 Issues 的时候,能够提供这些信息,也会大大的减少沟通成本。这将极大的提升框架开发人员的开发体验。