CRA 项目 create-react-app 请谨慎升级 TypeScript

本文解决了 create-react-app 或 react-scripts 项目在升级 TypeScript v4 到 v5 遇到的问题,还讲解了 TypeScript v5 新的 const 类型参数 语法。

问题

一个使用官方 create-react-app 的项目,某次为了引入 ts-pattern 将 TypeScript 从 v4 升级到 v5,随后在安装或移除其他依赖的时候报错:

vbnet 复制代码
❯ npm uninstall markdown-it-katex 
npm error code ERESOLVE
npm error ERESOLVE could not resolve
...
npm error
npm error Conflicting peer dependency: typescript@4.9.5
npm error node_modules/typescript
npm error   peerOptional typescript@"^3.2.1 || ^4" from react-scripts@5.0.1

重点:peerOptional typescript@"^3.2.1 || ^4" from react-scripts@5.0.1。

翻译一下就是 react-scripts 写死了 TypeScript 的范围,但是 CRA (create-react-app) 或 react-scripts 已经不维护和更新了,没法给其提 PR,社区也已有 issue,我们只能自己想办法。

CRA 不维护:

Upgrade TypeScript to v5 in React-scripts #13283

github.com/facebook/cr...

CRA is pretty much dead. I advise switching to vite. I have done this for a few projects, and it is really straight forward.

方案 1:vite

方案 1 迁移到 vite,但是我们项目步子还不想跨的这么大。

方案 2:--legacy-peer-deps

报错之后 npm 紧接着给了一个解决方案,但是我觉得不是很好,因为其针对的范围太大而不仅仅是 TypeScript 的版本不匹配问题:

vbnet 复制代码
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.  

也就是在每次 npm install/uninstall 的时候增加 flag --force or --legacy-peer-deps,或者在 .npmrc 中新增就无需每次安装或卸载都加。

方案 3:overrides

项目 package.json 增加 overrides(如果你是其他包管理也有相应的字段,比如 yarn 的 resolution):

perl 复制代码
  "dependencies": {
    "typescript": "^5.8.3",
  }
  "// 为了升级 typescript 到 v5(ts-pattern 以及趋势) 但 react-scripts 限定了 v4 导致下面的报错": "",
  "// fix Could not resolve dependency: npm error peerOptional typescript@\"^3.2.1 || ^4\" from react-scripts@5.0.1": "",
  "// overrides 比 --force 或 --legacy-peer-deps 更安全因为可以精确锁定某个依赖的版本": "",
  "overrides": {
    "typescript": "$typescript"
  },

注意 "$typescript" 这是一种引用写法,当然你可以写成 ^5.8.3,但引用是一种更好的方式,以后更新 TypeScript 版本此处无需随着变化。注意不能写死版本号 "5.8.3",否则报错 EOVERRIDE:

vbnet 复制代码
❯ npm uninstall markdown-it-katex
npm error code EOVERRIDE
npm error Override for typescript@^5.8.3 conflicts with direct dependency

更多阅读

json 复制代码
{
  "pnpm": {
    "overrides": {
      "foo": "^1.0.0",
      "quux": "npm:@myorg/quux@^1.0.0",
      "bar@^2.1.0": "3.0.0",
      "qar@1>zoo": "2"
    }
  }
}

pnpm 同样支持引用 "bar": "$foo",还支持删除某个依赖 "foo@1.0.0>heavy-dep": "-",比如某个大的依赖没有用到,从而减少安装时间。

为何安装 ts-pattern 需要升级 TypeScript

最后回答一个问题,为什么 ts-pattern 需要升级到 ts v5。ts-pattern 引入了一个新的语法:"const 类型参数" (const type parameters)。

ts 复制代码
export declare function match<const input, output = symbols.unset>(value: input): Match<input, output>;

即此处的 const input,如果不升级将报错:match doesnt work (Expected 0 arguments, but got 1) 。

详见我的另一篇文章:TypeScript v5 一个非常有用的新语法:"const 类型参数"。

相关推荐
miofly7 小时前
GitHub 今日推荐|rea:用 MCP 把反编译器和 AI agent 接到一起的逆向工具
typescript·开源·github
ZoeLandia17 小时前
React11:数据请求与 TanStack Query
前端·react.js·typescript·react
瓦瓦gogo17 小时前
实习中接触前端开发后,我开始了解 React
前端·react.js·前端框架
康小旺1 天前
AI 写 Vue 总写成同一个味道:给它装 Skills,装的不是知识是边界
vue.js·typescript
ZoeLandia2 天前
React08:自定义 Hook
开发语言·前端·react.js·typescript
aloha_7893 天前
HTML、JavaScript 与 TypeScript 基础速查
javascript·typescript·html
空中湖3 天前
用 React 写数据大屏:为什么我不建议用图表库
前端·react.js·前端框架
离歌漠3 天前
《我用 Tauri 做了一个本地开发工具箱》
rust·typescript·vue
enjoy编程4 天前
playwright学习-I
typescript·vue·nodejs·1024程序员节·playwright
iDao技术魔方4 天前
Bun v1.4.4 实战:用 bun fmt 替掉 prettier 的 5 个步骤
typescript·1024程序员节