0

В настоящее время я сравниваю Google Closure Compiler и статический тип проверки Flow с точки зрения выразительности. Что мне нравится в последнем, так это то, что он, по-видимому, вполне может быть 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? Это означает какой-то способ заставить определенные свойства объекта не только быть определенного типа, но иметь фиксированное значение? И использовать это значение для вывода типа, чтобы различать разные варианты в объединении? Я не нашел никакой документации по этому поводу.

ответ

1

Нет точного перевода. Вот как бы я это пишу:

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

Существует также несколько способов записи этих типов. Выбор, который вы выбираете, зависит от того, что вы хотите проверить. Например, вам нужно предупреждение, если вы ошибаетесь (или пытаетесь добавить) свойство? Вы хотите точное совпадение имен и типов свойств или разрешенных дополнительных свойств?

+0

Не знал, что можно использовать 'enum' как тип. Если я возьму вас на себя, обе формы, которые вы предлагаете, говорят, что свойство 'status' может быть одним из двух значений, не фиксируя связь между значением и соответствующим типом. Возможно, для этой цели будет использоваться один элемент 'enum' для каждого типа ... Вам придется немного поэкспериментировать с этим. – MvG

+0

Можно использовать Enum с одним значением –