还没用熟 TypeScript 社区已经开始抛弃了
共 7106字,需浏览 15分钟
· 2023-06-20
根据 rich-harris-talks-sveltekit-and-whats-next-for-svelte[1] 这篇文章的报道, Svelte 计划要把代码从 TS 换到 JS 了。
The team is switching the underlying code from TypeScript[2] to JavaScript[3]. That and the update will then allow the team to incorporate “big ideas” for Svelte 5 later this year, he added.
这种震惊劲爆的信息,当然的核实下是不是准确的,于是去 svelte 框架的作者 Rich Harris 的推特去求证下,好奇的不止我一个,已经有人提问了,并且作者给出了答案,非常确定:
最新消息,非常确定了,就在昨天,北京时间 2022 年 5 月 9 日,Svelte 团队发布了一个名为 TS to JSDoc Conversion[4] 的 PR,开始这项浩瀚的工程,同时宣布目前 Svelte 不再支持重大更新了,根据点不支持的人数,看到这件事情比较有争议,不支持的人不在少数。
事实上,这不是社区第一次放弃 TypeScript 了,比如 Deno 远在 2020 年就弃用了 TS[5],并给出三大理由:
-
减少了构建时间 -
发布代码变小了 -
写的代码大大减少了
那个时候 TyepScript 的发展正在如日中天的时候,广大库的作者普遍拥抱 TS,比如于2020年9月18日正式发布的Vue3 ,代号为 One Piece(海贼王)。
三年过去了,再好看的媳妇也看腻了,大家就开始挑毛病了,你(TyepScript)可能并不完美。
回归了理性,大家就开始思考使用 TyepScript 的初心是什么了,意识吼出了灵魂一问?我们为什么使用 TypeScript?
没错,这个问题很简单,因为 TypeScript 提供了类型检查,弥补了 JavaScript 只有逻辑没有类型的问题,也就是讲我们不需要 TypeScript 的逻辑,只需要它的的类型提示功能。但是不知不觉之间,我们在逻辑的道路上越走越远。
比如下面是 Vue3 watch API 的类型声明,我估计给一天时间,大多数人可能都不太能整的明白里面的逻辑:
export declare function watch<
T extends MultiWatchSources,
Immediate extends Readonly<boolean> = false,
>(
sources: [...T],
cb: WatchCallback<MapSources<T, false>, MapSources<T, Immediate>>,
options?: WatchOptions<Immediate>,
): WatchStopHandle;
export declare function watch<
T extends Readonly<MultiWatchSources>,
Immediate extends Readonly<boolean> = false,
>(
source: T,
cb: WatchCallback<MapSources<T, false>, MapSources<T, Immediate>>,
options?: WatchOptions<Immediate>,
): WatchStopHandle;
export declare function watch<T, Immediate extends Readonly<boolean> = false>(
source: WatchSource<T>,
cb: WatchCallback<T, Immediate extends true ? T | undefined : T>,
options?: WatchOptions<Immediate>,
): WatchStopHandle;
export declare function watch<T extends object, Immediate extends Readonly<boolean> = false>(
source: T,
cb: WatchCallback<T, Immediate extends true ? T | undefined : T>,
options?: WatchOptions<Immediate>,
): WatchStopHandle;
而且如果项目引用了用 TypeScript 编写的库,需要频繁借助 VSCode 等编辑器查看源代码,才能进行类型声明继续编写逻辑代码。
以前我也是 TypeScript 的拥趸,但是使用了一两年之后,我改变了看法,平时应付业务逻辑已经够费脑子了,现在需要花不少时间去调整代码来适应需求。
除此之外,dev 开发代码进行类型检查也比较费时间,项目大了可能需要顿个几秒才能检查完成,再进行代码编译输出到浏览器。
现在明白了最初的需求,完全可以用 JavaScript + JSDoc[6] 来解决类型声明,现代编辑器是认的 JSDoc,友好支持程度一点不比 TS 差,如果是编写库,需要导出给安装者使用,那就在 .d.ts 文件中定义导出给使用者。
使用 JSDoc 表达类型,不仅省去了构建步骤,不打包都可以直接用,还可以避免编写复杂的类型逻辑,太方便了有没有,代码可以复制到任何 JS 的运行环境心动没有。
我们来实践看看行不行的通,光说不练,假把式。
这里以 Svgo 的一个函数 removeLeadingZero[7] 为例,这个函数可以删除小数的前导零并作为字符串返回,比如 0.5 → .5
和 -0.5 → \-.5
:
const removeLeadingZero = (num) => {
let strNum = num.toString();
if (0 < num && num < 1) {
strNum = strNum.slice(1);
} else if (-1 < num && num < 0) {
strNum = "-" + strNum.slice(2);
}
return strNum;
};
我们添加如何注释:
markdown
复制代码
`/**
-
Remove floating-point numbers leading zero. -
-
@example -
0.5 → .5 -
-
@example -
-0.5 → -.5 -
-
@type {(num: number) => string} */`
非常好用:
实际上 VSCode 有智能推断,简单的代码都能推断出来,比如,const num = 23;
会自动感应出来方法:
说回来 removeLeadingZero 函数,当我们调用的时候,传入错误的参数,没有像 TS 类型强制报错:
解决办法也很简单,比如:
-
利用的 TS _\@ts-check_ 注释
-
添加 `tsconf.json` / `jsconfig.json` 并让 checkJs 为 true。
{
"compilerOptions": {
"checkJs": true
},
"exclude": ["node_modules", "**/node_modules/*"]
}
-
添加 "js/ts.implicitProjectConfig.checkJs": true
到您的工作区或用户设置里面即settings.json
文件。 -
更多参考 type-checking-javascript[8]
改正后的效果:
事实上 JSDoc 的类型注释非常丰富比如还有 @param
、@const
等等,但不复杂,学习成本很低。
参考
-
rich-harris-talks-sveltekit-and-whats-next-for-svelte[9] -
TypeScript vs JSDoc という対立は存在しない、と思った話[10] -
removeLeadingZero[11] -
type-checking-javascript[12] -
how-to-use-jsdoc-annotations-with-vscode-for-intellisense-7co[13]
参考资料
https://thenewstack.io/rich-harris-talks-sveltekit-and-whats-next-for-svelte/
[2]https://thenewstack.io/key-concepts/typescript/
[3]https://thenewstack.io/jamstack-panel-multiple-javascript-frameworks-are-a-good-thing/
[4]https://github.com/sveltejs/svelte/pull/8569
[5]https://github.com/denoland/deno/pull/6793
[6]https://www.typescriptlang.org/ja/docs/handbook/jsdoc-supported-types.html
[7]https://github.com/svg/svgo/blob/main/lib/svgo/tools.js#LL128C7-L128C24
[8]https://code.visualstudio.com/docs/nodejs/working-with-javascript#_type-checking-javascript
[9]https://thenewstack.io/rich-harris-talks-sveltekit-and-whats-next-for-svelte/
[10]https://qiita.com/fsd-tetsu/items/d8b50481b6c735ffa6f3
[11]https://github.com/svg/svgo/blob/main/lib/svgo/tools.js#LL128C7-L128C24
[12]https://code.visualstudio.com/docs/nodejs/working-with-javascript#_type-checking-javascript
[13]https://dev.to/sumansarkar/how-to-use-jsdoc-annotations-with-vscode-for-intellisense-7co
The End
最后不要忘了点赞呦!