闭包编译器中的标记联合

Tagged unions in closure compiler

我目前正在很好地比较 Google Closure Compiler and the Flow static type checker, in terms of expressiveness. What I like about the latter is that it apparently can represent tagged unions。手册给出了这个例子:

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 做这样的事情?这意味着某种方法可以强制对象的某些属性不仅具有特定类型,而且具有固定值?并使用该值进行类型推断,以区分联合中的不同选项?我没有找到这方面的文档。

没有准确的翻译。以下是我的写法:

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

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