还没用熟 TypeScript 社区已经开始抛弃了
根据 rich-harris-talks-sveltekit-and-whats-next-for-svelte 这篇文章的报道, Svelte 计划要把代码从 TS 换到 JS 了。
The team is switching the underlying code from TypeScript to JavaScript. 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 的 PR,开始这项浩瀚的工程,同时宣布目前 Svelte 不再支持重大更新了,根据点不支持的人数,看到这件事情比较有争议,不支持的人不在少数。

事实上,这不是社区第一次放弃 TypeScript 了,比如 Deno 远在 2020 年就弃用了 TS,并给出三大理由:
- 减少了构建时间
- 发布代码变小了
- 写的代码大大减少了
那个时候 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 来解决类型声明,现代编辑器是认的 JSDoc,友好支持程度一点不比 TS 差,如果是编写库,需要导出给安装者使用,那就在 .d.ts 文件中定义导出给使用者。
使用 JSDoc 表达类型,不仅省去了构建步骤,不打包都可以直接用,还可以避免编写复杂的类型逻辑,太方便了有没有,代码可以复制到任何 JS 的运行环境心动没有。
我们来实践看看行不行的通,光说不练,假把式。
这里以 Svgo 的一个函数 removeLeadingZero 为例,这个函数可以删除小数的前导零并作为字符串返回,比如 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; };
我们添加如何注释:
/** * 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
改正后的效果:

事实上 JSDoc 的类型注释非常丰富比如还有 @param、@const 等等,但不复杂,学习成本很低
相关文章:
还没用熟 TypeScript 社区已经开始抛弃了
根据 rich-harris-talks-sveltekit-and-whats-next-for-svelte 这篇文章的报道, Svelte 计划要把代码从 TS 换到 JS 了。 The team is switching the underlying code from TypeScript to JavaScript. That and the update will then allow the team to incorporate…...
2023年9月19日
2> 完成文本编辑器的保存工作 头文件 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QFontDialog> #include <QMainWindow> #include <QFont> #include <QMessageBox> #include <QDebug> #include <QColorDialog> #include &l…...
PowerDesigner 与 mysql 同步数据
PowerDesigner 连接上数据库 创建数据库表 table_5 选择: 点击确认后弹出 点击run执行 刷新数据库表,已创建成功 修改测试表1,新增一个字段 取消全选 选择数据库,勾选修改的表,如果全部勾选的话,就…...
[python 刷题] 271 Encode and Decode Strings
[python 刷题] 271 Encode and Decode Strings 题目: Design an algorithm to encode a list of strings to a string. The encoded string is then sent over the network and is decoded back to the original list of strings. Machine 1 (sender) has the func…...
[QT]day3
1.一个闹钟 widget.cpp: #include "widget.h" #include "ui_widget.h"#include <QWidget> #include <QTimerEvent> //定时器事件处理类 #include <QTime>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {//给播…...
《PostgreSQL事务管理深入解析》
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🐅🐾猫头虎建议程序员必备技术栈一览表📖: 🛠️ 全栈技术 Full Stack: 📚…...
深度分析Oracle中的NULL
【squids.cn】 全网zui低价RDS,免费的迁移工具DBMotion、数据库备份工具DBTwin、SQL开发工具等 关键点 特殊值NULL意味着没有数据,它声明了该值是未知的事实。默认情况下,任何类型的列和变量都可以取这个值,除非它们有一个NOT N…...
Python入门教学——类和对象
目录 一、面向过程和面向对象 1、面向过程 2、面向对象 二、类 三、类对象与类属性 1、类对象 2、类属性 四、类方法与静态方法 1、类方法 2、静态方法 一、面向过程和面向对象 1、面向过程 是一种以过程为中心的编程思想,强调事件的流程和顺序。思想&…...
【数据库系统概论】关系数据库中的关系数据结构
前言关系关系模式关系数据库关系模型的存储结构感谢 💖 前言 上一篇文章【数据库系统概论】数据模型介绍了数据库系统中的数据模型的基本概念。其中提到了关系模型是最重要的一种数据模型。下面将介绍支持关系模型的数据库系统——关系数据库。 按照数据模型的三大…...
LabVIEW对Table中同一行数据分多次增加
LabVIEW对Table中同一行数据分多次增加 在对多个设备采集数据,同时需要记录到表格中。很多时候多台数据并不是同时更新,比如有的是在开关之前读取更新,有的则是在开关闭合后更新。只是用Number Indicator的方式,需要很多个&#…...
微信小程序实现删除功能
1. 前端 项目列表展示是使用的wx:for遍历 每个项目展示有3个模块 1. project-title 2. project-content 3. project-foot 全部代码如下 <t-sticky><view class"search"><t-search model:value"{{conditions.keyword}}" pl…...
整合Shiro+Jwt
整合ShiroJwt大体思路 springboot整合shiro大体上的思路: 1.自定义一个类Realm extends AuthorizingRealm{} 主要是对token授权和认证 重写2个方法 doGetAuthorizationInfo //授权 doGetAuthenticationInfo //认证 认证 代码中手动加上对token校验的判断2.自…...
Python 图形化界面基础篇:创建工具栏
Python 图形化界面基础篇:创建工具栏 引言 Tkinter 库简介步骤1:导入 Tkinter 模块步骤2:创建 Tkinter 窗口步骤3:创建工具栏步骤4:向工具栏添加工具按钮步骤5:处理工具按钮的点击事件步骤6:启动…...
基于matlab实现的卡尔曼滤波匀加速直线运动仿真
完整程序: clear clc %% 初始化参数 delta_t 0.1; %采样时间 T 8; %总运行时长 t 0:delta_t:T; %时间序列 N length(t); %序列的长度 x0 0; %初始位置 u0 0; %初速度 U 10; %控制量、加速度 F [1 delta_t 0 1]; %状态转移矩阵 B …...
windows Visual Studio 2022 opengl开发环境配置
1. 安装glew(GL), GLFW, glm, soil2-debug 还需要premake生成visual studio solution cmake for windows也要安装一个, 但是不用安装MinGW64, bug多 下载源码,找到xxx.sln文件用visual stidio打开solution编译代码,找到xxx.lib, xxx.dll文件…...
中国财政科学研究院党委书记、院长刘尚希一行莅临麒麟信安调研
为贯彻落实省委第十二届四次全会精神,加快推动湖南高质量发展,9月16日下午,由中国财政科学研究院党委书记、院长刘尚希,中国电子信息产业发展研究院总工程师秦海林,省委改革办副主任梁仲,省发展改革委党组成…...
基于element-ui的年份范围选择器
基于element-ui的年份范围选择器 element-ui官方只有日期范围和月份范围选择器,根据需求场景需要,支持年份选择器,原本使用两个分开的年份选择器实现的,但是往往有些是不能接受的。在网上找了很多都没有合适的,所以打…...
【已解决】您所使用的密钥ak有问题,不支持jsapi服务,可以访问该网址了解如何获取有效密钥。
您所使用的密钥ak有问题,不支持jsapi服务,可以访问该网址了解如何获取有效密钥。详情查看:http://lbsyun.baidu.com/apiconsole/key#。 问题 百度密钥过期 思路 注册成为开发者 如果还没注册百度地图api账号的,点击以后就进入…...
JS操作数组方法学习系列(1)
目录 数组添加元素 (push)数组移除末尾元素 (pop)数组添加元素到开头 (unshift)数组移除开头元素 (shift)数组查找元素索引 (indexOf)数组反向查找元素索引 (lastIndexOf)数组切割 (slice)数组连接 (concat)数组元素查找 (find 和 findIndex)数组元素过滤 (filter)数组元素映射…...
翻牌闯关游戏
翻牌闯关游戏 3关:关卡由少至多12格、20格、30格图案:12个玩法:点击两张卡牌,图案一到即可消除掉 记忆时长(毫秒):memoryDurationTime:5000 可配置:默认5000 提示游戏玩法:showTipsFlag:1 可…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合
无论是python,或者java 的大型项目中,都会涉及到 自身平台微服务之间的相互调用,以及和第三发平台的 接口对接,那在python 中是怎么实现的呢? 在 Python Web 开发中,FastAPI 和 Django 是两个重要但定位不…...
网页端 js 读取发票里的二维码信息(图片和PDF格式)
起因 为了实现在报销流程中,发票不能重用的限制,发票上传后,希望能读出发票号,并记录发票号已用,下次不再可用于报销。 基于上面的需求,研究了OCR 的方式和读PDF的方式,实际是可行的ÿ…...
LeetCode - 148. 排序链表
目录 题目 思路 基本情况检查 复杂度分析 执行示例 读者可能出的错误 正确的写法 题目 148. 排序链表 - 力扣(LeetCode) 思路 链表归并排序采用"分治"的策略,主要分为三个步骤: 分割:将链表从中间…...
