1

我目前正在比较Google Closure CompilerFlow静态类型检查器的表现力。我喜欢后者的是它显然可以很好地代表标记的联合。手册给出了这个例子:

type Result = Done | Error; // a disjoint union type with two cases
type Done = { status: 'done', answer: Matrix };
type Error = { status: 'error', message: string };

有没有办法使用 Closure Compiler 来做这样的事情?这意味着某种方式可以强制对象的某些属性不仅是特定类型,而且具有固定值?并使用该值进行类型推断,以区分联合中的不同选项?我没有找到有关此效果的文档。

4

1 回答 1

2

没有准确的翻译。这是我写这个的方法:

/** @enum {string} */
var ResultStatus = {
  DONE: 'done',
  ERROR: 'error'
};

/** @record */
var Done = function() {};

/** @type {ResultStatus} */
Done.prototype.status;

/** @type {Matrix} */
Done.prototype.answer;

/** @record */
var Error = function() {};

/** @type {ResultStatus} */
Error.prototype.status;

/** @type {string} */
Error.prototype.message;

/** @type {Result|Error} */
var Result;

这是一个非常冗长的语法,但提供了最好的类型检查。假定具有这些属性的任何对象都与类型匹配。允许额外的属性。

有一个更短的语法,行为略有不同:typedefs。

/** @enum {string} */
var ResultStatus = {
  DONE: 'done',
  ERROR: 'error'
};

/**
 * @typedef{{
 *   status: ResultStatus
 *   answer: Matrix
 * }}
 */
var Done;

/**
 * @typedef{{
 *   status: ResultStatus
 *   message: string
 * }}
 */
var Error;

/** @type {Result|Error} */
var Result;

还有其他几种编写这些类型的方法。您选择哪个取决于您要检查的内容。例如,如果您拼错(或尝试添加)某个属性,您是否需要警告?您想要两个属性名称或类型完全匹配,还是允许额外的属性?

于 2016-12-17T14:10:24.687 回答