本文解决了 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
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
更多阅读
- 上述写法灵感来自:github.com/rainlanguag...
- 引用写法 npm 官方文档:docs.npmjs.com/cli/v10/con...
- bun 也是和 npm 一样用
overrides
但是也可以写成 resolutions 因为 bun 需要让 yarn 用户平滑迁移。 - pnpm 写法 pnpm.io/9.x/package... 最新版 v10 没有介绍 overrides 如何写,估计兼容 v9。
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 类型参数"。