前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JSDoc ,一个可替代 TypeScript 的方案?

JSDoc ,一个可替代 TypeScript 的方案?

作者头像
前端达人
发布2023-11-14 17:31:08
7490
发布2023-11-14 17:31:08
举报
文章被收录于专栏:前端达人

许多开发者喜欢使用TypeScript,因为它具有类型检查功能。然而,这需要额外的转译步骤,可能会带来麻烦和浪费时间。本文将向您展示如何使用JSDoc来获得相同类型的控制,同时使用纯JavaScript进行最快的开发时间和更好的文档编写!

JavaScript已经巩固了其作为近年来最常用的脚本语言之一的地位。它以在Web平台上编写脚本的简易性而闻名。随着语言的发展,它从最初只是一个利用Java成功的“玩具”语言,发展成为一个用于构建不仅仅是小型脚本的完整语言。

不幸的是,这揭示了语言的缺陷。其中一些包括:

  • 缺乏静态类型和严格的类型检查:JavaScript非常宽容,允许将参数传递给不接受它的函数,可以省略必需的值等。这在静态类型语言中是不允许的,因为会在编译时出错。这些错误会在JavaScript应用程序中出现在生产环境中。
  • JavaScript在扩展和维护大型代码库方面存在困难:JavaScript没有提供强大的机制来管理大型代码库,这使得随着时间的推移,项目的扩展和维护变得具有挑战性。

Typescript

2014年,微软推出了TypeScript v1.0。这改变了整个JavaScript生态系统。

TypeScript是JavaScript的超集,解决了上述问题以及更多问题。这使得它在最近的时间里越来越受欢迎。

2022年的State of Js调查显示TypeScript的使用率上升。

TypeScript 在解决了许多问题的同时,也并非没有缺点。

在本文中,我们将介绍一种非常好的 TypeScript 替代方案,名为 JSDoc,它解决了静态类型和可扩展性的问题,同时也消除了 TypeScript 在 JavaScript 生态系统中的一些缺点。

JSDoc是什么?

JSDoc是一个用于JavaScript的文档系统。它通过使用包含JSDoc语法的注释来工作。

JSDoc语法具有多种用途,包括用类型注释值,为函数指定参数和返回类型,为函数提供文档和使用信息,以及类型错误等。类似于TypeScript,这些可以被代码编辑器利用,作为指导程序员构建、使用或维护所述代码库的指南。

JSDoc VS TypeScript

JSDoc和TypeScript都解决了编写和维护纯JavaScript代码的问题。然而,它们采用了不同的方法,各有利弊。

JSDoc相对于TypeScript的优势:

  • 灵活性和兼容性:JSDoc只是JavaScript注释,这意味着它可以添加到任何JavaScript代码库中,而不受语言版本的限制,并且不像TypeScript那样与编译器绑定。
  • 代码注释:JSDoc不仅可以用于类型检查,还可以用于添加更多的文档,描述函数的工作原理,并生成文档网站,从而提供价值以增强代码的可维护性和理解性。
  • 无需编译步骤:这是从TypeScript转换到JSDoc最具动力的原因之一。TypeScript需要编译将TypeScript代码转换为JavaScript,以便浏览器能够理解,而JSDoc不需要任何其他步骤,因为它们只是“注释”,这是JavaScript本身支持的特性。与每次进行更改时都需要使用必要的TypeScript构建流程相比,这可以简化并加快开发工作流程。

使用JSDoc的缺点

虽然JSDoc相对于TypeScript有很多优势,但是随着时间的推移,TypeScript的使用越来越普遍。以下是TypeScript相对于JSDoc的一些优势:

  • 更强大的静态类型:TypeScript提供了一种强大的类型模型,并在编译时捕获这些错误。与JSDoc不同,这些类型在代码本身中结束,并且不受强制执行。
  • 类型推断:TypeScript 可以从其值推断类型。这有助于减少显式类型注解,使代码库更简洁。
  • 转译:TypeScript 可以通过其 polyfill 功能采用 JavaScript 语言的最新和未来特性。它可以将这些代码有效地转译成可理解的版本,以适应尚未支持这些特性的浏览器。

如何使用JSDoc:基础知识

由于其长期存在,JSDoc在所有现代编辑器中都得到了广泛支持,并且可以直接使用,无需任何安装。

在一个 .js 文件中添加JSDoc,如所述只是注释,通过使用额外的 * 开启一个注释来完成

代码语言:javascript
复制
// Normal Javascript Comment 1
/* Normal Javascript Comment 2 */ 

/** 
 JSDoc containing two asterisks
  */

这些是一些入门的基本功能。

向代码块添加代码描述:

代码语言:javascript
复制
/** The name of the language JSDoc is written for*/
const language = "JavaScript"

为值添加类型:

代码语言:javascript
复制
/** 
 * This represents the writer of this blog
 * @type {string}
 */
const writerName = "Elijah"

现在,指定用户名变量应为字符串类型。

向对象和数组添加类型:

代码语言:javascript
复制
/** 
* @type {Array<string>}
*/
const colours = ['red', 'blue', 'green']

/**
 * @type {number[]}
 */
const primeNumbers = [1, 2, 3, 5, 7]

两种方法在JSDoc中都是有效的(与Typescript相同)。

通过使用 @typedef 指令可以创建一个对象类型。

代码语言:javascript
复制
/**
 * * @typedef {Object} User - A user schema 
 * @property {number} id 
 * @property {string} username
 * @property {string} email
 * @property {Array<number>} postLikes
 * @property {string[]} friends
 */
代码语言:javascript
复制
/**@type {User} */
const person1 = {
  id: 847,
  username: "Elijah",
  email: "elijah@user.com",
  postLikes: [44, 22, 24, 39],
  friends: ['fede', 'Elijah']
}
代码语言:javascript
复制
/** @type {User} */
const person2 = {
id: 424,
username: "Winston",
email: "winston@user.com",
postLike: [18, 53, 98],
friends: ['Favour', 'Jane']
}

输入函数(参数、返回值和预期错误类型):

代码语言:javascript
复制
/**
 * Divide two numbers.
 * @param {number} dividend - The number to be divided.
 * @param {number} divisor - The number to divide by.
 * @returns {number} The result of the division.
 */
function divideNumbers(dividend, divisor) {
    return dividend/divisor;
}

关键字 @param 后面定义一个类型,表示定义的函数将接受的值。你也可以在连字符(-)后面加上参数的描述。

关键字 @returns 用于定义函数返回的内容。这对于大型函数特别有用。可能很难浏览所有的代码,包括早期返回,以确定函数的预期行为。

此外,您可以使用 @throws 指令添加函数可能抛出的错误。

改进除法函数,我们可以指定如果除数为零则返回错误,并在代码中处理这种情况。

代码语言:javascript
复制
/**
 * Divide two numbers.
 * @param {number} dividend - The number to be divided.
 * @param {number} divisor - The number to divide by.
 * @returns {number} The result of the division.
 * @throws {ZeroDivisionError} Argument divisor must be non-zero
 */
function divideNumbers(dividend, divisor) {
    if (divisor === 0) {
        throw new DivisionByZeroError('Cannot Divide by zero')
    }
    return dividend/divisor;
}

@throws 可以接受错误类型(ZeroDivisionError)或描述(参数除数必须…)或两者皆有。

代码语言:javascript
复制
/**
 * Custom error for division by zero.
 */
class DivisionByZeroError extends Error {
    constructor(message = "Cannot Divide By Zero") {
        super(message);
      this.name = "DivisionByZeroError";
    }
}

由于JavaScript本身不会强制你处理错误,因此你必须这样做,因为它有助于提高协作和维护。

输入完整的类(描述、构造函数和方法)

更进一步,您还可以使用JSDoc输入完整的类语法。

代码语言:javascript
复制
/**
 * A Rectangle Class
 * @class
 * @classdec A four-sided polygon with opposite sides of equal length and four right angles
 */
class Rectangle {
  /**
   * Initializing a Rectangle object.
   * @param {number} length - The length of the rectangle.
   * @param {number} width - The width of the rectangle.
   */
  constructor(length, width) {
    this.length = length;
    this.width = width;
  }

  /**
   * Calculate the area of the rectangle.
   * @returns {number} The area of the rectangle.
   */
  calculateArea() {
    return this.length * this.width;
  }

  /**
   * Calculate the perimeter of the rectangle.
   * @returns {number} The perimeter of the rectangle.
   */
  calculatePerimeter() {
    return 2 * (this.length + this.width);
  }
}

上面是一个简单的矩形类,有两个方法来计算它的面积和周长。

@class 关键字用于表示需要使用 new 关键字调用的函数。 @classdec 用于描述整个类。在编写类时,通过添加类型和描述来进一步完善是很重要的。

  • 构造函数
  • 类中创建的所有方法和变量

我们使用 @params 关键字来提供需要传递给构造函数的参数的类型和描述。类中的方法与函数的类型方式相同,这在前一节中已经介绍过。

改进通用代码文档:

除了在代码中添加必要的类型之外,JSDoc还有很多方法可以提高可读性和理解的便利性。以下是其中的几个:

添加代码作者:可以使用 @author 指令添加项目的作者,包括作者的姓名和电子邮件

代码语言:javascript
复制
 /**
     * Possible title for this article
    * @type {string} 
    * @author Elijah [elijah@example.com]
    */
const articleTitle =  "Demystifying JSDoc"

你还可以添加代码片段,展示特定代码块的使用方法。这对于复杂的代码块尤其有用。

代码语言:javascript
复制
/** 
 * Sums of the square of two numbers a**2 + b**2
 * @example <caption>How to use the sumSquares function</caption>
 * // returns 13 
 * sumSquares(2, 3)
 * @example
 * // returns 41
 * sumSquares(4, 5)
 * // Typing the function
 * @param {number} a - The first number
 * @param {number} b - The second number
 * @returns {Number} Returns the sum of the squares
 * */
const sumSquares = function(a, b){
    return a**2 + b**2
}

我们使用 @example 指令来实现这一点。这也可以用 caption 标签来加注。

版本控制:您还可以使用 @version 指令指定项目的版本。

代码语言:javascript
复制
/** 
 * @version 1.0.0
 * @type {number} 
 * */
const meaningOfLife = 42

有用的链接:通常,您可能希望将用户指向其他地方,以便他们可以获取有关代码的更多知识。这可以是一个GitHub存储库、一些教程、博客等。为了实现这一点,有两个指令可以帮助实现。 @link 和 @tutorial 。

代码语言:javascript
复制
/** 
 * How to use the link tags
 * Also see the {@link https://jsdoc.app/tags-inline-link.html official docs} for more information
 * @tutorial getting-started
 * */
function myFunction (){
}

@link 标签将 official docs 渲染为指定链接的链接。它用于创建到指定URL的链接,而 @tutorial 标签用于将用户引导到生成的文档中的相对教程链接。

创建模块:在JSDoc中创建模块可以使用文件顶部的 @module 标签。这将使当前文件成为一个模块。模块将在生成的文档网站上的单独部分中进行分组。

代码语言:javascript
复制
// jsdoc.js
/** @module firstDoc */
//The rest of the code goes here

转换 JSDoc 文件

使用JSDoc的最大优点之一是能够将JSDoc文件转换为文档网站,甚至转换为Typescript,以便享受使用Typescript的好处,如在编译时捕获错误、与Typescript项目集成等。

从JSDoc文件生成文档网站

如上所述,按照以下步骤可以制作出更易读的图形用户界面:

安装 jsdoc

代码语言:javascript
复制
npm install -g jsdoc

运行 jsdoc 以获取目标文件

代码语言:javascript
复制
jsdoc path/to/file.js

这是默认生成的模板的样子,但你可以配置模板的外观。

从JSDoc生成.d.ts文件

在TypeScript中, .d.ts 文件代表包含所有 .ts 文件都可以访问的类型声明文件。您可以通过以下步骤从JSDoc代码生成这些文件:

在项目文件夹中安装 tsd-jsdoc

代码语言:javascript
复制
npm install tsd-jsdoc

生成 .d.ts 文件

对于一个单独的文件

代码语言:javascript
复制
jsdoc -t node_modules/tsd-jsdoc/dist -r our/jsdoc/file/path.js

对于多个文件

代码语言:javascript
复制
jsdoc -t node_modules/tsd-jsdoc/dist -r file1.js file2.js file3.js ...

对于整个文件夹

代码语言:javascript
复制
jsdoc -t node_modules/tsd-jsdoc/dist -r src

它将所有类型的文件合并成一个 out/types.d.ts 文件。

注意:这假设您已经从前一节安装了 jsdoc 。如果没有,请先安装它,然后再运行此步骤。

结论

到目前为止,我们已经学会了使用JSDoc的基础知识,以及从JSDoc代码生成类型和文档网站。JSDoc在以下情况下特别有用:当您的Typescript编译时间/构建步骤对生产力产生相反的影响时,以及在处理遗留代码库时。

Rich Harris(Svelte 和 SvelteKit 的创始人)将整个 Svelte 和 SvelteKit 仓库从 TypeScript 转移到了 JSDoc。TypeScript 也已经为许多 JSDoc 声明添加了支持(来源)。

由于文章内容篇幅有限,今天的内容就分享到这里,文章结尾,我想提醒您,文章的创作不易,如果您喜欢我的分享,请别忘了点赞和转发,让更多有需要的人看到。同时,如果您想获取更多前端技术的知识,欢迎关注我,您的支持将是我分享最大的动力。我会持续输出更多内容,敬请期待。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-11-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端达人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Typescript
  • JSDoc是什么?
  • JSDoc VS TypeScript
  • 如何使用JSDoc:基础知识
  • 输入函数(参数、返回值和预期错误类型):
  • 转换 JSDoc 文件
  • 从JSDoc生成.d.ts文件
  • 结论
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档