本文探讨在JavaScript中使用JSDoc实现静态类型检查的可行性。JSDoc允许开发者在不引入TypeScript编译步骤的情况下获得类型安全,适用于无需编译的小型脚本或CLI工具。通过配置tsconfig.json启用allowJs和checkJs,IDE可提供与.ts文件同等的分析体验。
引言
这种场景是否似曾相识:你打算编写一个小型脚本,可能是用于网页、命令行工具或其他用途。起初你使用JavaScript进行开发,但随着编码深入,你意识到缺乏类型定义会带来诸多不便。于是,你将文件扩展名从.js更改为.ts,却随即发现这引入了一系列复杂问题。
若你正在开发网站或库,必须引入编译环节。若是编写CLI脚本,虽可借助原生支持TypeScript的Deno,但仍需配置IDE以识别Deno API,且Deno与Node.js环境的混用往往并不顺畅。
本地开发完成后,还需考虑代码分发:是否需检查编译后的.js文件?是否需构建CI流水线以自动编译.ts文件?若发布库,又该如何确保其他项目能顺利引用?
你实际上不需要TypeScript
核心观点在于:获取静态类型分析功能,并不必然要求使用TypeScript。
借助JSDoc注释,JavaScript同样能享受TypeScript带来的类型优势。
TypeScript的核心价值在于其静态类型系统,该类型信息在运行时并不存在。执行TypeScript代码时,所有类型数据均被剥离(这也解释了为何无法通过运行时测试来验证变量类型)。
换言之,TypeScript仅为编译器提供的额外元数据,对JavaScript引擎无实际意义。编译过程本质上是移除类型注解,还原为标准JavaScript代码。
JSDoc
在JavaScript诞生25年多后,JSDoc作为一种注释JavaScript代码的方式被引入。它是一种正式的标记语言,允许IDE在开发者看到一个函数时提供额外的上下文。
此类注释标记广泛存在于多种编程语言中,其基本形式如下:
/**
* This is the JSDOC block. IDEs will show this text when you hover the
* printName function.
*
* @param {string} name
*/
function printName(name) {
console.log(name)
}TypeScript 和 JSDoc
鲜为人知的是,JSDoc足以支撑TypeScript的全部类型功能。TypeScript编译器能解析JSDoc中的类型定义,并提供与.ts文件一致的静态分析能力。
此处不赘述完整语法,但需明确:.ts文件中的绝大多数功能,均可通过JSDoc实现。示例如下:
原生类型函数参数示例:
/**
* @param {string} a
* @param {number} b
*/
function foo(a, b) {}利用TypeScript内置类型:
/**
* @param {HTMLElement} element
* @param {Window} window
*/
function foo(element, window) {}
/** @type {number[]} */
let years对象字面量与函数定义:
/** @type {{ name: string; age: number }} */
let person
/** @type {(s: string, b: boolean) => void} */
let myCallback从*.d.ts文件导入类型:
/** @param {import('./types').User} user */
const deleteUser = (user) => {}定义复用类型:
/**
* @typedef {object} Color
* @property {number} chroma
* @property {number} hue
*/
/** @type {Color[]} */
const colors = [
{ chroma: 0.2, hue: 262 },
{ chroma: 0.2, hue: 28.3 },
]详细语法请参阅官方TypeScript JSDoc文档。
若涉及复杂类型,仍可编写*.d.ts文件并在JSDoc中导入。
注意,项目仍需配置TypeScript环境(含IDE),并创建tsconfig.json文件,将编译器选项allowJs与checkJs设为true:
// tsconfig.json
{
"compilerOptions": {
"allowJs": true,
"checkJs": true
// ...
}
}什么时候写TypeScript
尽管JSDoc可实现全类型声明,但便捷性不及TypeScript。TS语法更简洁且冗余更少。
TypeScript团队提出的“作为注释的类型”ECMAScript提案,允许TypeScript代码直接在JS引擎中运行(类型被视为注释)。
在该提案正式落地前,开发者需在JSDoc与TypeScript工具链间做出选择。
建议
综合建议如下:
- 涉及编译步骤的项目,使用TypeScript并无弊端。
- 若无编译需求,坚持使用JSDoc类型注释更为简便。
原文翻译自 https://www.pausly.app/blog/full-type-support-with-plain-javascript
以上就是问题解析有JSDoc还需要TypeScript吗的详细内容,更多关于JSDoc TypeScript解析的资料请关注本站其它相关文章!