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

相关推荐
LRH1 小时前
时间切片 + 双工作循环 + 优先级模型:React 的并发任务管理策略
前端·react.js
歪歪1001 小时前
React Native开发有哪些优势和劣势?
服务器·前端·javascript·react native·react.js·前端框架
XiaoSong2 小时前
React Native 主题配置终极指南,一篇文章说透
前端·react native·react.js
im_AMBER15 小时前
React 01
前端·javascript·笔记·react.js·前端框架·web
@大迁世界15 小时前
React 19.2.0 有哪些新变化
前端·javascript·react.js·前端框架·ecmascript
duandashuaige20 小时前
解决用electron打包Vue工程(Vite)报错electron : Failed to load URL : xxx... with error : ERR _CONNECTION_REFUSED
javascript·typescript·electron·npm·vue·html
今天头发还在吗20 小时前
React + Ant Design 日期选择器避免显示“Invalid Date“的解决方案
前端·react.js·前端框架·ant design
sjin1 天前
React源码 - 关键数据结构
前端·react.js
IT小哥哥呀1 天前
论文见解:REACT:在语言模型中协同推理和行动
前端·人工智能·react.js·语言模型
古茗前端团队1 天前
小程序 Galacean Effect实践
react.js