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 类型参数"

相关推荐
烬羽7 小时前
React Router v7 完全指南:一个 Demo 吃透前端路由
javascript·react.js·前端框架
烬羽7 小时前
React Router 嵌套路由:一个 `Outlet` 引发的布局思考
react.js·面试·前端框架
kyriewen10 小时前
别再这样写条件渲染了——你的React组件里藏着这5种定时炸弹
前端·javascript·react.js
用户9385156350711 小时前
从"坐电梯"到"前端路由"——深入理解 Hash 路由原理
前端·typescript·全栈
mONESY12 小时前
🎨 从零搭建 React + TypeScript + Vite 项目:以 Color Picker 为例,聊聊前端工程化的 model/api 分层架构
react.js
苏灿烤鱼14 小时前
GitHub Trending 榜首|腾讯 Agent 记忆库技术拆解:分层记忆 vs 向量堆,让 AI 不再反复问
typescript·开源·agent
用户9385156350715 小时前
React 组件设计的三个层次:从类型约束到状态归属,再到纯展示
typescript·全栈
阿黎梨梨19 小时前
从“能用”到“好维护”:React + TypeScript 实战指南
react.js
无人生还19 小时前
从 Vue3 到 React · 快速上手系列第 11 篇:状态管理
前端·vue.js·react.js
GuWenyue19 小时前
90%前端写React TS都踩坑!一套父子组件+Hooks完整实战,彻底搞懂类型约束
前端·react.js