是否可以在ES6项目中使用自定义类型定义?

cgm*_*123 9 javascript typechecking node.js ecmascript-6 visual-studio-code

我的团队在一个相对较大的NodeJS项目上工作,用ES6编写,由babel编译,然后用无服务器部署为AWS lambdas.该项目主要围绕消费,映射/转换以及输出我们定义的一种特定对象类型.

我们的问题是,ECMA/JavaScript不是强类型的,所以如果我们犯了一个错误,就像将某个字段视为某个地方的数组而将字符串视为其他地方,除了运行时错误之外没有什么可以捕获的.我们也很难记录这个对象的结构,所以有时消费者会向我们发送带有数据的对象的实例,这些数据在我们说过的有些错误名称的字段中,但实际上并没有使用.

我正在寻找一种方法来为我们项目中的特定对象创建某种模式或类型定义,因此我们可以使用它来纠正我们的代码,使我们的处理更加健壮,并为它创建更好的文档.现在,我知道VSCode 在JavaScript中提供了一些基本的类型检查,但我认为尝试将JSDoc作为一个非常大的对象然后将该文档放在使用该对象的每个文件中是不可行的.我发现VSCode也能以某种方式用.d.ts文件驱动检查,但我不明白我是否或如何利用它来为我们设计的特定自定义对象.我发现的大多数内容似乎与为外部库提取.d.ts文件特别相关.

那么,TL:DR,在NodeJS/ES6项目中,是否有可能在整个项目中广泛使用一个强类型的对象?在VSCode中检查错误是可以接受的,但是在转换之前我们可以触发的某种命令行linting也会很好.

cgm*_*123 5

好吧,想通了.在我发布这个问题之后,我一直在谷歌搜索,一小时左右在Sequoia McDowell的StrongLoop上发表这篇文章:https://strongloop.com/strongblog/type-hinting-in-javascript/

我非常密切地关注它,使用"typings"包,我能够在项目的根目录初始化一个"typings"文件夹.该文件夹的内容现在如下所示:

typings/
??? models/
?   ??? myObject.d.ts
??? index.d.ts
Run Code Online (Sandbox Code Playgroud)

index.d.ts文件的内容如下所示:

/// <reference path="models/myObject.d.ts" />
Run Code Online (Sandbox Code Playgroud)

而myObject.d.ts文件的内容看起来像这样模糊:

declare namespace MyProject {
  export interface MyObject {
    aString?: string;
    anotherString?: string;
    aComplexType?: ComplexType;
  }

  interface ComplexType {
    aString?: string;
    anotherComplexType: SecondComplexType;
  }

  interface SecondComplexType {
    aString?: string;
  }
}
Run Code Online (Sandbox Code Playgroud)

完成后,我不得不用JSDoc开始标记这个对象的实例.该doc主要有两种形式:

/**
 * Creates an instance of UtilityThing.
 * @param {MyProject.MyObject} myObject
 *
 * @memberof UtilityThing
 */
constructor(myObject) {
  this.myObject = myObject;
}

/**
 * @param {MyProject.MyObject} myObject
 * @returns {MyProject.MyObject}
 */
function noOp(myObject) {
  return myObject;
}
Run Code Online (Sandbox Code Playgroud)

/** @type {MyProject.MyObject} */
const myObject = containerObject.myObject;
Run Code Online (Sandbox Code Playgroud)

通过这个设置,以及VSCode的最新公开发布,我能够看到我正在编辑的ES6*.js文件中的错误告诉我哪些属性不存在,哪些属性被分配了错误类型的值,被认为是错误的类型等

中途那里.

经过一些研究,我发现这并不是一个独特的VSCode功能.看来他们正在使用"tslint"或它的一些定制版本.使用这些知识,我在项目中添加了"tslint"并编写了这个npm脚本:

"tslint": "tslint --type-check --project tsconfig.json"
Run Code Online (Sandbox Code Playgroud)

以下是我登陆的tsconfig.json的内容,但我并不完全确定所有这些选项都是必需的.

{
  "compilerOptions": {
    "target": "es6",
    "allowJs": true,
    "noResolve": true,
    "checkJs": true,
    "moduleResolution": "node",
    "types": [
      "node"
    ]
  },
  "exclude": [
    "node_modules",
    "coverage",
    "lib",
    "spec"
  ]
}
Run Code Online (Sandbox Code Playgroud)

使用该tsconfig.json运行此"tslint"脚本,以及"typings"文件夹中的类型定义文件,允许我使用正确的JSDoc在项目中的所有文件中键入一个特定的对象类型.我确实遇到了一个小问题,但似乎已经修复并在大约一小时前合并,巧合的是.除了类型检查对象的字段之外,这还揭示了一些属性过早地从其后代实际具有该属性的对象中拉出的地方.很酷.

TL; DR:可以做到这一点,非常感谢Sequoia McDowell的那篇文章,最终让我走上正轨.