还没用熟 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 不再支持重大更新了,根据点不支持的人数,看到这件事情比较有争议,不支持的人不在少数。

TS to JSDoc Conversion

事实上,这不是社区第一次放弃 TypeScript 了,比如 Deno 远在 2020 年就弃用了 TS[5],并给出三大理由:

  1. 减少了构建时间
  2. 发布代码变小了
  3. 写的代码大大减少了

那个时候 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<TImmediate 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 objectImmediate 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} */`

非常好用:

image.png

实际上 VSCode 有智能推断,简单的代码都能推断出来,比如,const num = 23; 会自动感应出来方法:

image.png

说回来 removeLeadingZero 函数,当我们调用的时候,传入错误的参数,没有像 TS 类型强制报错:

image.png

解决办法也很简单,比如:

  1. 利用的 TS _\@ts-check_ 注释
  2. 添加 `tsconf.json` / `jsconfig.json` 并让 checkJs 为 true。
{
 "compilerOptions": {
   "checkJs"true
 },
 "exclude": ["node_modules""**/node_modules/*"]
}
  1. 添加"js/ts.implicitProjectConfig.checkJs": true到您的工作区或用户设置里面即 settings.json 文件。
  2. 更多参考 type-checking-javascript[8]

改正后的效果:

image.png

事实上 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]

参考资料

[1]

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


关于本文
来源:CondorHero
https://juejin.cn/post/7218117377052377143

The End


如果你觉得这篇内容对你挺有启发,我想请你帮我三个小忙:
1、点个 「在看」,让更多的人也能看到这篇内容
2、关注官网 https://muyiy.cn,让我们成为长期关系
3、关注公众号「高级前端进阶」,公众号后台回复 「加群」 ,加入我们一起学习并送你精心整理的高级前端面试题。

》》面试官都在用的题库,快来看看《


      
         

最后不要忘了点赞呦!

      
         


浏览 5
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报