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

Is it possible to use custom type definitions in an ES6 project?

我的团队在一个相对较大的 NodeJS 项目上工作,该项目用 ES6 编写,由 babel 转译,然后使用无服务器部署为 AWS lambda。该项目专注于消费、mapping/transforming 和输出我们定义的一种特定对象类型。

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

我正在寻找一种方法来为我们项目中的这个特定对象创建某种模式或类型定义,以便我们可以使用它来更正我们的代码,使我们的处理更健壮,并为创建更好的文档它。现在,我知道 VSCode 提供了一些 basic type checking in JavaScript, but I don't think it's feasible to try to JSDoc a really big object and then put that doc in every file that uses the object. I have found that VSCode can also, somehow, drive that checking with .d.ts files 但我不明白我是否可以或如何将其用于我们设计的特定自定义对象。我发现的大部分内容似乎都与为外部库提取 .d.ts 文件特别相关。

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

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

检查此 link:https://basarat.gitbooks.io/typescript/docs/quick/nodejs.html

好的,明白了。在我发布这个问题之后,我一直在谷歌搜索,大约一个小时后,我点击了 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 的最新 public 版本,我能够看到我当前正在编辑的 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"
  ]
}

运行 这个 "tslint" 脚本,那个 tsconfig.json 和 "typings" 文件夹中的类型定义文件允许我在整个过程中对一个特定的对象类型进行类型检查使用适当的 JSDoc 在项目中创建文件。我将 运行 变成了 small issue,但巧合的是,它似乎已在大约一个小时前修复并合并。除了对对象的字段进行类型检查外,这还揭示了几个地方的属性被过早地从一个对象中提取出来,而该对象的后代实际上具有该属性。很酷。

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

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

VS 代码版本: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