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

时间:2017-05-31 13:57:03

标签: javascript node.js ecmascript-6 visual-studio-code typechecking

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

我们的问题是,ECMA / JavaScript不是强类型的,所以如果我们把某个字段视为某个地方的数组和其他地方的字符串会出错,除了运行时错误之外没有什么可以捕获的。我们也没有很好地记录这个对象的结构,所以有时消费者会向我们发送带有数据的对象实例,这些数据位于我们称之为处理过的但名字不多的字段中,但实际上并没有使用。

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

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

3 个答案:

答案 0 :(得分:5)

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

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

typings/
├── models/
│   └── myObject.d.ts
└── index.d.ts

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

/// <reference path="models/myObject.d.ts" />

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;
  }
}

完成后,我不得不用JSDoc开始标记这个对象的实例。该文件主要采取两种形式:

/**
 * 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;
}

/** @type {MyProject.MyObject} */
const myObject = containerObject.myObject;

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

中途。

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

"tslint": "tslint --type-check --project tsconfig.json"

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

{
  "compilerOptions": {
    "target": "es6",
    "allowJs": true,
    "noResolve": true,
    "checkJs": true,
    "moduleResolution": "node",
    "types": [
      "node"
    ]
  },
  "exclude": [
    "node_modules",
    "coverage",
    "lib",
    "spec"
  ]
}

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

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

答案 1 :(得分:1)

你不能强大的Javascript类型,即使你可以,你不应该,javascript被创建为动态语言,但在打字稿中你可以

结帐此链接:https://basarat.gitbooks.io/typescript/docs/quick/nodejs.html

答案 2 :(得分:0)

我发现你可以在JS文件的开头设置// @ts-check,并且*.d.ts文件将被识别(至少在项目的根目录下)。

VS Code版本:1.22

编辑:

所以我用这个内容创建了jsconfig.json

{
  "compilerOptions": {
    "jsx": "react",
    "checkJs": true,
    "noResolve": true, // because some imports didn't work
    "moduleResolution": "node" // because of npm i <git or local dependency>
  },
  "include": ["src/**/*", "types/**/*"],
  "exclude": ["node_modules"]
}

types文件夹中,我有多个文件*.d.ts

一切正常,您不需要明确设置// @ts-check