是否可以在ES6项目中使用自定义类型定义? [英] Is it possible to use custom type definitions in an ES6 project?

查看:266
本文介绍了是否可以在ES6项目中使用自定义类型定义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的团队致力于一个相对较大的NodeJS项目,该项目用ES6编写,由babel进行编译,然后与Serverless一起部署为AWS lambda.该项目专注于消费,映射/转换和输出我们定义的一种特定对象类型.

My team works on a relatively large NodeJS project, written in ES6, transpiled by babel, and then deployed as AWS lambdas with Serverless. This project is focused around consuming, mapping/transforming, and outputting one specific object type, which we have defined.

我们的问题是,ECMA/JavaScript的类型不是很强,所以如果我们犯了一个错误,例如将某个字段视为一个数组作为数组,而将字符串作为其他地方作为字符串,那么除了运行时错误外,没有其他东西可以抓住.我们也没有很好地记录该对象的结构,因此有时消费者向我们发送该对象的实例,并在我们说我们处理但实际上不使用的字段中稍有错误地使用了数据.

Our problem is, ECMA/JavaScript is not strongly typed, so if we make a mistake like treating a field as an array somewhere and a string somewhere else, there's nothing to catch that except runtime errors. We have also poorly documented the structure of this object, so sometimes consumers send us instances of the object with data in slightly misnamed fields that we say we process, but don't actually use.

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

I am looking for a way to create some kind of schema or type definition for this specific object in our project, so we can use that to correct our code, make our processing more robust, and create much better documentation for it. Now, I know VSCode offers some 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 but I don't understand if or how I can leverage that for a specific, custom object that we've designed. Most of what I have found seems to be specifically related to pulling .d.ts files for external libraries.

因此,TL:DR,在NodeJS/ES6项目中是否可以使一个在整个项目中广泛使用的对象得到强类型化?在VSCode中进行错误检查是可以接受的,但是我们可以在转译之前触发的某种命令行检测方法也很好.

So, TL:DR, Is it possible, in a NodeJS/ES6 project, to make one object, widely used throughout that project, strongly typed? Error checking in VSCode would be acceptable, but some kind of command-line linting that we could trigger before transpiling would be great too.

推荐答案

好的,解决了.发布此问题后,我一直进行谷歌搜索,大约一个小时后,由Sequoia McDowell在StrongLoop上发布了这篇文章: https://strongloop.com/strongblog/type-hinting-in-javascript/

Alright, figured it out. After I posted this question, I kept googling and after an hour or so hit this article on StrongLoop by Sequoia McDowell: https://strongloop.com/strongblog/type-hinting-in-javascript/

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

I followed it pretty closely and, using the "typings" package, I was able to initialize a "typings" folder at the root of my project. The contents of that folder now look like this:

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

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

The content of that index.d.ts file look like this:

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

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

And the contents of that myObject.d.ts file look something vaguely like this:

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

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

  interface SecondComplexType {
    aString?: string;
  }
}

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

With that done, I had to start marking instances of this object with JSDoc. That doc mainly took two forms:

/**
 * 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文件中的错误,该错误告诉我哪些属性不存在,哪些属性被分配了错误的值.类型,这些类型被认为是错误的类型,等等.

With this setup, and the latest public release of VSCode, I was able to see errors in ES6 *.js files that I was currently editing that told me which attributes didn't exist, which were being assigned values of the wrong type, which were assumed to be the wrong type, etc.

那边的半路.

经过更多研究,我发现这并不是VSCode的独特功能.似乎他们使用的是"tslint"或它的某些自定义版本.利用这些知识,我在项目中添加了"tslint"并制定了以下npm脚本:

After some more research, I figured out that this isn't exactly a unique VSCode feature. It seems that they're using "tslint" or some customized version of it. Working with that knowledge, I added "tslint" to the project and worked out this npm script:

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

这是我登陆的tsconfig.json的内容,尽管我不确定是否完全需要所有这些选项.

Here are the contents of the tsconfig.json that I landed on, though I'm not entirely sure all of these options are needed.

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

运行带有tsconfig.json的"tslint"脚本和"typings"文件夹中的类型定义文件,使我可以使用适当的JSDoc在整个项目的所有文件中键入检查一种特定的对象类型.我确实遇到了小问题,但这似乎已经解决并合并了大约一个小时巧合的是除了对对象的字段进行类型检查之外,这还揭示了几个地方,该属性是从对象的后代实际上具有该属性的对象中过早地拉出该属性的.很酷.

Running this "tslint" script, with that tsconfig.json, and the type definition files in the "typings" folder allows me to type check one specific object type throughout all files in the project with proper JSDoc. I did run into a small issue but that seems to have been fixed and merged about an hour ago, coincidentally. In addition to type checking the object's fields, this also revealed a couple of places where an attribute was prematurely being pulled from an object whose descendant actually had that attribute. Very cool.

TL; DR:可以完成,这要感谢红杉麦克道尔(Sequoia McDowell)的那篇文章,它使我最终走上了正确的道路.

TL;DR: It can be done, huge thanks to Sequoia McDowell for that article which finally set me on the right track.

这篇关于是否可以在ES6项目中使用自定义类型定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆