message: refactor(compiler): use type guard rather than type cast
  The code will now fail if the `i18n` property is of the wrong type.
  PR Close
diff: @@ -231,19 +231,23 @@ class HtmlAstToIvyAst implements html.Visitor {
  }
  visitExpansion(expansion: html.Expansion): t.Icu|null {
  - const meta = expansion.i18n as i18n.Message;
  + if (!expansion.i18n) {
  // do not generate Icu in case it was created
  // outside of i18n block in a template
  - if (!meta) {
  return null;
  }
  + if (!isI18nRootNode(expansion.i18n)) {
  + throw new Error(
  + `Invalid type "${expansion.i18n.constructor}" for "i18n" property of ${expansion.sourceSpan.toString()}. Expected a "Message"`);
  + }
  + const message = expansion.i18n;
  const vars: {[name: string]: t.BoundText} = {};
  const placeholders: {[name: string]: t.Text | t.BoundText} = {};
  // extract VARs from ICUs - we process them separately while
  // assembling resulting message via goog.getMsg function, since
  // we need to pass them to top-level goog.getMsg call
  - Object.keys(meta.placeholders).forEach(key => {
  - const value = meta.placeholders[key];
  + Object.keys(message.placeholders).forEach(key => {
  + const value = message.placeholders[key];
  if (key.startsWith(I18N_ICU_VAR_PREFIX)) {
  const config = this.bindingParser.interpolationConfig;
  // ICU expression is a plain string, not wrapped into start
  @@ -254,7 +258,7 @@ class HtmlAstToIvyAst implements html.Visitor {
  placeholders[key] = this._visitTextWithInterpolation(value, expansion.sourceSpan);
  }
  });
  - return new t.Icu(vars, placeholders, expansion.sourceSpan, meta);
  + return new t.Icu(vars, placeholders, expansion.sourceSpan, message);
  }
  visitExpansionCase(expansionCase: html.ExpansionCase): null { return null; }
  