2

有JSDoc还需要TypeScript吗

 1 year ago
source link: https://www.51cto.com/article/756389.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

这听起来是不是很耳熟:你想写一个小型脚本,不管是为页面、命令行工具,还是其他什么类型。你从JavaScript开始,直到你想起写代码时没有类型是多么痛苦。所以你把文件从.js重命名为.ts。然后意识到你已经打开了一个麻烦的玩意儿。

如果你在为一个网站或一个库写代码,你就需要引入编译的步骤。如果你在编写CLI脚本,你可以求助于Deno(它支持TypeScript,开箱即用),但是你需要设置你的IDE来理解Deno的API,而且混合和匹配Deno和node并不总是那么容易。

一旦你在本地完成了所有工作,你就需要考虑如何分发你的代码。你会检查你编译的.js文件吗?你会创建一个CI管道来自动编译你的.ts文件吗?如果你在写一个库,你如何发布你的库,以便它可以被其他项目使用?

你实际上不需要TypeScript

问题是......你不需要为了获得静态类型分析而编写TypeScript!

你可以通过使用JSDoc在JavaScript中获得TypeScript的所有好处

TypeScript所提供的是一个静态类型系统。这意味着类型信息在运行代码中没有影响。当你的TypeScript被执行时,所有的类型信息都会完全丢失(这就是为什么你不写一个类型守卫,就不能测试一个变量是否是某个类型的原因)。

这也意味着TypeScript只是提供给TypeScript分析器的额外类型信息,对运行你代码的JavaScript引擎没有任何意义。当你把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文档[1]以获得详尽的列表。

如果你有复杂的类型,你仍然可以编写你的*.d.ts文件并在你的JSDoc注释中导入它们。

注意,你仍然需要为typescript设置你的项目(和IDE),你需要创建一个tsconfig.json文件,将编译器选项allowJs和checkJs设置为true:

// tsconfig.json
{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": true
    // ...
  }
}

什么时候写TypeScript

虽然完全使用JSDoc进行类型声明是可能的,但这并不是最方便的。TypeScript的语法要好得多,而且不那么重复。

TypeScript团队创建了一个"作为注释的类型"ECMAScript提案[2],允许你编写TypeScript并在不修改的情况下在JavaScript引擎中运行(JavaScript引擎将把这些类型注释视为注释。)

但是在这个提案被接受之前,我们只能决定使用JSDoc或者TypeScript工具链。

所以现在我的建议是这样的:

  • 当你正在做一个有编译步骤的项目时,使用TypeScript没有什么坏处
  • 但是如果你不需要编译步骤,那么坚持使用JSDoc类型注释可能更容易。

本文译自:https://www.pausly.app/blog/full-type-support-with-plain-javascript[3]

以上就是本文的全部内容,如果对你有所帮助,欢迎点赞、收藏、转发~

[1]文档:https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html

[2]ECMAScript提案:https://github.com/tc39/proposal-type-annotations

[3]https://www.pausly.app/blog/full-type-support-with-plain-javascript:https://www.pausly.app/blog/full-type-support-with-plain-javascript


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK